xref: /reactos/drivers/bus/acpi/busmgr/bus.c (revision c2c66aff)
1 /*
2  *  acpi_bus.c - ACPI Bus Driver ($Revision: 80 $)
3  *
4  *  Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com>
5  *
6  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
7  *
8  *  This program is free software; you can redistribute it and/or modify
9  *  it under the terms of the GNU General Public License as published by
10  *  the Free Software Foundation; either version 2 of the License, or (at
11  *  your option) any later version.
12  *
13  *  This program is distributed in the hope that it will be useful, but
14  *  WITHOUT ANY WARRANTY; without even the implied warranty of
15  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  *  General Public License for more details.
17  *
18  *  You should have received a copy of the GNU General Public License along
19  *  with this program; if not, write to the Free Software Foundation, Inc.,
20  *  59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
21  *
22  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
23  */
24 
25  /*
26   * Modified for ReactOS and latest ACPICA
27   * Copyright (C)2009  Samuel Serapion
28   */
29 
30 #include <precomp.h>
31 
32 #define NDEBUG
33 #include <debug.h>
34 
35 #define _COMPONENT		ACPI_BUS_COMPONENT
36 ACPI_MODULE_NAME		("acpi_bus")
37 
38 #define WALK_UP			0
39 #define WALK_DOWN		1
40 
41 #define STRUCT_TO_INT(s)	(*((int*)&s))
42 #define HAS_CHILDREN(d)		((d)->children.next != &((d)->children))
43 #define HAS_SIBLINGS(d)		(((d)->parent) && ((d)->node.next != &(d)->parent->children))
44 #define NODE_TO_DEVICE(n)	(list_entry(n, struct acpi_device, node))
45 
46 int			event_is_open;
47 extern void acpi_pic_sci_set_trigger(unsigned int irq, UINT16 trigger);
48 
49 typedef int (*acpi_bus_walk_callback)(struct acpi_device*, int, void*);
50 
51 struct acpi_device		*acpi_root;
52 KSPIN_LOCK	acpi_bus_event_lock;
53 LIST_HEAD(acpi_bus_event_list);
54 //DECLARE_WAIT_QUEUE_HEAD(acpi_bus_event_queue);
55 KEVENT AcpiEventQueue;
56 KDPC event_dpc;
57 
58 int ProcessorCount, PowerDeviceCount, PowerButtonCount, FixedPowerButtonCount;
59 int FixedSleepButtonCount, SleepButtonCount, ThermalZoneCount;
60 
61 static int
acpi_device_register(struct acpi_device * device,struct acpi_device * parent)62 acpi_device_register (
63 	struct acpi_device	*device,
64 	struct acpi_device	*parent)
65 {
66 	int			result = 0;
67 
68 	if (!device)
69 		return_VALUE(AE_BAD_PARAMETER);
70 
71 	return_VALUE(result);
72 }
73 
74 
75 static int
acpi_device_unregister(struct acpi_device * device)76 acpi_device_unregister (
77 	struct acpi_device	*device)
78 {
79 	if (!device)
80 		return_VALUE(AE_BAD_PARAMETER);
81 
82 #ifdef CONFIG_LDM
83 	put_device(&device->dev);
84 #endif /*CONFIG_LDM*/
85 
86 	return_VALUE(0);
87 }
88 
89 
90 /* --------------------------------------------------------------------------
91                                 Device Management
92    -------------------------------------------------------------------------- */
93 
94 void
acpi_bus_data_handler(ACPI_HANDLE handle,void * context)95 acpi_bus_data_handler (
96 	ACPI_HANDLE		handle,
97 	void			*context)
98 {
99 	DPRINT1("acpi_bus_data_handler not implemented\n");
100 
101 	/* TBD */
102 
103 	return;
104 }
105 
106 
107 int
acpi_bus_get_device(ACPI_HANDLE handle,struct acpi_device ** device)108 acpi_bus_get_device (
109 	ACPI_HANDLE		handle,
110 	struct acpi_device	**device)
111 {
112 	ACPI_STATUS		status = AE_OK;
113 
114 	if (!device)
115 		return_VALUE(AE_BAD_PARAMETER);
116 
117 	/* TBD: Support fixed-feature devices */
118 
119 	status = AcpiGetData(handle, acpi_bus_data_handler, (void**)device);
120 	if (ACPI_FAILURE(status) || !*device) {
121 		DPRINT( "Error getting context for object [%p]\n",
122 			handle);
123 		return_VALUE(AE_NOT_FOUND);
124 	}
125 
126 	return 0;
127 }
128 
acpi_bus_get_status_handle(ACPI_HANDLE handle,unsigned long long * sta)129 ACPI_STATUS acpi_bus_get_status_handle(ACPI_HANDLE handle,
130 				       unsigned long long *sta)
131 {
132 	ACPI_STATUS status;
133 
134 	status = acpi_evaluate_integer(handle, "_STA", NULL, sta);
135 	if (ACPI_SUCCESS(status))
136 		return AE_OK;
137 
138 	if (status == AE_NOT_FOUND) {
139 		*sta = ACPI_STA_DEVICE_PRESENT | ACPI_STA_DEVICE_ENABLED |
140 		       ACPI_STA_DEVICE_UI      | ACPI_STA_DEVICE_FUNCTIONING;
141 		return AE_OK;
142 	}
143 	return status;
144 }
145 
146 int
acpi_bus_get_status(struct acpi_device * device)147 acpi_bus_get_status (
148 	struct acpi_device	*device)
149 {
150 	ACPI_STATUS status;
151 	unsigned long long sta;
152 
153 	status = acpi_bus_get_status_handle(device->handle, &sta);
154 	if (ACPI_FAILURE(status))
155 		return -1;
156 
157 	STRUCT_TO_INT(device->status) = (int) sta;
158 
159 	if (device->status.functional && !device->status.present) {
160 		ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device [%s] status [%08x]: "
161 		       "functional but not present;\n",
162 			device->pnp.bus_id,
163 			(UINT32) STRUCT_TO_INT(device->status)));
164 	}
165 
166 	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device [%s] status [%08x]\n",
167 			  device->pnp.bus_id,
168 			  (UINT32) STRUCT_TO_INT(device->status)));
169 	return 0;
170 }
171 
acpi_bus_private_data_handler(ACPI_HANDLE handle,void * context)172 void acpi_bus_private_data_handler(ACPI_HANDLE handle,
173 				   void *context)
174 {
175 	return;
176 }
177 
acpi_bus_get_private_data(ACPI_HANDLE handle,void ** data)178 int acpi_bus_get_private_data(ACPI_HANDLE handle, void **data)
179 {
180 	ACPI_STATUS status = AE_OK;
181 
182 	if (!*data)
183 		return -1;
184 
185 	status = AcpiGetData(handle, acpi_bus_private_data_handler, data);
186 	if (ACPI_FAILURE(status) || !*data) {
187 		DPRINT("No context for object [%p]\n", handle);
188 		return -1;
189 	}
190 
191 	return 0;
192 }
193 /* --------------------------------------------------------------------------
194                                  Power Management
195    -------------------------------------------------------------------------- */
196 
197 int
acpi_bus_get_power(ACPI_HANDLE handle,int * state)198 acpi_bus_get_power (
199 	ACPI_HANDLE		handle,
200 	int			*state)
201 {
202 	int			result = 0;
203 	ACPI_STATUS             status = 0;
204 	struct acpi_device	*device = NULL;
205 	unsigned long long		psc = 0;
206 
207 	result = acpi_bus_get_device(handle, &device);
208 	if (result)
209 		return_VALUE(result);
210 
211 	*state = ACPI_STATE_UNKNOWN;
212 
213 	if (!device->flags.power_manageable) {
214 		/* TBD: Non-recursive algorithm for walking up hierarchy */
215 		if (device->parent)
216 			*state = device->parent->power.state;
217 		else
218 			*state = ACPI_STATE_D0;
219 	}
220 	else {
221 		/*
222 		 * Get the device's power state either directly (via _PSC) or
223 		 * indirectly (via power resources).
224 		 */
225 		if (device->power.flags.explicit_get) {
226 			status = acpi_evaluate_integer(device->handle, "_PSC",
227 				NULL, &psc);
228 			if (ACPI_FAILURE(status))
229 				return_VALUE(AE_NOT_FOUND);
230 			device->power.state = (int) psc;
231 		}
232 		else if (device->power.flags.power_resources) {
233 			result = acpi_power_get_inferred_state(device);
234 			if (result)
235 				return_VALUE(result);
236 		}
237 
238 		*state = device->power.state;
239 	}
240 
241 	DPRINT("Device [%s] power state is D%d\n",
242 		device->pnp.bus_id, device->power.state);
243 
244 	return_VALUE(0);
245 }
246 
247 
248 int
acpi_bus_set_power(ACPI_HANDLE handle,int state)249 acpi_bus_set_power (
250 	ACPI_HANDLE		handle,
251 	int			state)
252 {
253 	int			result = 0;
254 	ACPI_STATUS		status = AE_OK;
255 	struct acpi_device	*device = NULL;
256 	char			object_name[5] = {'_','P','S','0'+state,'\0'};
257 
258 
259 	result = acpi_bus_get_device(handle, &device);
260 	if (result)
261 		return_VALUE(result);
262 
263 	if ((state < ACPI_STATE_D0) || (state > ACPI_STATE_D3))
264 		return_VALUE(AE_BAD_PARAMETER);
265 
266 	/* Make sure this is a valid target state */
267 
268 	if (!device->flags.power_manageable) {
269 		DPRINT1( "Device is not power manageable\n");
270 		return_VALUE(AE_NOT_FOUND);
271 	}
272 	/*
273 	 * Get device's current power state
274 	 */
275 	//if (!acpi_power_nocheck) {
276 		/*
277 		 * Maybe the incorrect power state is returned on the bogus
278 		 * bios, which is different with the real power state.
279 		 * For example: the bios returns D0 state and the real power
280 		 * state is D3. OS expects to set the device to D0 state. In
281 		 * such case if OS uses the power state returned by the BIOS,
282 		 * the device can't be transisted to the correct power state.
283 		 * So if the acpi_power_nocheck is set, it is unnecessary to
284 		 * get the power state by calling acpi_bus_get_power.
285 		 */
286 		acpi_bus_get_power(device->handle, &device->power.state);
287 	//}
288 
289 	if ((state == device->power.state) && !device->flags.force_power_state) {
290 		DPRINT1("Device is already at D%d\n", state);
291 		return 0;
292 	}
293 	if (!device->power.states[state].flags.valid) {
294 		DPRINT1( "Device does not support D%d\n", state);
295 		return AE_NOT_FOUND;
296 	}
297 	if (device->parent && (state < device->parent->power.state)) {
298 		DPRINT1( "Cannot set device to a higher-powered state than parent\n");
299 		return AE_NOT_FOUND;
300 	}
301 
302 	/*
303 	 * Transition Power
304 	 * ----------------
305 	 * On transitions to a high-powered state we first apply power (via
306 	 * power resources) then evalute _PSx.  Conversely for transitions to
307 	 * a lower-powered state.
308 	 */
309 	if (state < device->power.state) {
310 		if (device->power.flags.power_resources) {
311 			result = acpi_power_transition(device, state);
312 			if (result)
313 				goto end;
314 		}
315 		if (device->power.states[state].flags.explicit_set) {
316 			status = AcpiEvaluateObject(device->handle,
317 				object_name, NULL, NULL);
318 			if (ACPI_FAILURE(status)) {
319 				result = AE_NOT_FOUND;
320 				goto end;
321 			}
322 		}
323 	}
324 	else {
325 		if (device->power.states[state].flags.explicit_set) {
326 			status = AcpiEvaluateObject(device->handle,
327 				object_name, NULL, NULL);
328 			if (ACPI_FAILURE(status)) {
329 				result = AE_NOT_FOUND;
330 				goto end;
331 			}
332 		}
333 		if (device->power.flags.power_resources) {
334 			result = acpi_power_transition(device, state);
335 			if (result)
336 				goto end;
337 		}
338 	}
339 
340 end:
341 	if (result)
342 		DPRINT( "Error transitioning device [%s] to D%d\n",
343 			device->pnp.bus_id, state);
344 	else
345 		DPRINT("Device [%s] transitioned to D%d\n",
346 			device->pnp.bus_id, state);
347 
348 	return result;
349 }
350 
acpi_bus_power_manageable(ACPI_HANDLE handle)351 BOOLEAN acpi_bus_power_manageable(ACPI_HANDLE handle)
352 {
353 	struct acpi_device *device;
354 	int result;
355 
356 	result = acpi_bus_get_device(handle, &device);
357 	return result ? 0 : device->flags.power_manageable;
358 }
359 
acpi_bus_can_wakeup(ACPI_HANDLE handle)360 BOOLEAN acpi_bus_can_wakeup(ACPI_HANDLE handle)
361 {
362 	struct acpi_device *device;
363 	int result;
364 
365 	result = acpi_bus_get_device(handle, &device);
366 	return result ? 0 : device->wakeup.flags.valid;
367 }
368 
369 static int
acpi_bus_get_power_flags(struct acpi_device * device)370 acpi_bus_get_power_flags (
371 	struct acpi_device	*device)
372 {
373 	ACPI_STATUS             status = 0;
374 	ACPI_HANDLE		handle = 0;
375 	UINT32                     i = 0;
376 
377 	if (!device)
378 		return AE_NOT_FOUND;
379 
380 	/*
381 	 * Power Management Flags
382 	 */
383 	status = AcpiGetHandle(device->handle, "_PSC", &handle);
384 	if (ACPI_SUCCESS(status))
385 		device->power.flags.explicit_get = 1;
386 	status = AcpiGetHandle(device->handle, "_IRC", &handle);
387 	if (ACPI_SUCCESS(status))
388 		device->power.flags.inrush_current = 1;
389 	status = AcpiGetHandle(device->handle, "_PRW", &handle);
390 	if (ACPI_SUCCESS(status))
391 		device->flags.wake_capable = 1;
392 
393 	/*
394 	 * Enumerate supported power management states
395 	 */
396 	for (i = ACPI_STATE_D0; i <= ACPI_STATE_D3; i++) {
397 		struct acpi_device_power_state *ps = &device->power.states[i];
398 		char		object_name[5] = {'_','P','R','0'+i,'\0'};
399 
400 		/* Evaluate "_PRx" to se if power resources are referenced */
401 		status = acpi_evaluate_reference(device->handle, object_name, NULL,
402 			&ps->resources);
403 		if (ACPI_SUCCESS(status) && ps->resources.count) {
404 			device->power.flags.power_resources = 1;
405 			ps->flags.valid = 1;
406 		}
407 
408 		/* Evaluate "_PSx" to see if we can do explicit sets */
409 		object_name[2] = 'S';
410 		status = AcpiGetHandle(device->handle, object_name, &handle);
411 		if (ACPI_SUCCESS(status)) {
412 			ps->flags.explicit_set = 1;
413 			ps->flags.valid = 1;
414 		}
415 
416 		/* State is valid if we have some power control */
417 		if (ps->resources.count || ps->flags.explicit_set)
418 			ps->flags.valid = 1;
419 
420 		ps->power = -1;		/* Unknown - driver assigned */
421 		ps->latency = -1;	/* Unknown - driver assigned */
422 	}
423 
424 	/* Set defaults for D0 and D3 states (always valid) */
425 	device->power.states[ACPI_STATE_D0].flags.valid = 1;
426 	device->power.states[ACPI_STATE_D0].power = 100;
427 	device->power.states[ACPI_STATE_D3].flags.valid = 1;
428 	device->power.states[ACPI_STATE_D3].power = 0;
429 
430 	device->power.state = ACPI_STATE_UNKNOWN;
431 
432 	return 0;
433 }
434 
435 /* --------------------------------------------------------------------------
436                               Performance Management
437    -------------------------------------------------------------------------- */
438 
439 static int
acpi_bus_get_perf_flags(struct acpi_device * device)440 acpi_bus_get_perf_flags (
441 	struct acpi_device	*device)
442 {
443 	if (!device)
444 		return AE_NOT_FOUND;
445 
446 	device->performance.state = ACPI_STATE_UNKNOWN;
447 
448 	return 0;
449 }
450 
451 
452 /* --------------------------------------------------------------------------
453                                 Event Management
454    -------------------------------------------------------------------------- */
455 
456 void
457 NTAPI
acpi_bus_generate_event_dpc(PKDPC Dpc,PVOID DeferredContext,PVOID SystemArgument1,PVOID SystemArgument2)458 acpi_bus_generate_event_dpc(PKDPC Dpc,
459                             PVOID DeferredContext,
460                             PVOID SystemArgument1,
461                             PVOID SystemArgument2)
462 {
463 	struct acpi_bus_event *event;
464     struct acpi_device *device = SystemArgument1;
465     ULONG_PTR TypeData = (ULONG_PTR)SystemArgument2;
466 	KIRQL OldIrql;
467 
468     event = ExAllocatePoolWithTag(NonPagedPool,sizeof(struct acpi_bus_event), 'epcA');
469 	if (!event)
470 		return;
471 
472 	sprintf(event->device_class, "%s", device->pnp.device_class);
473 	sprintf(event->bus_id, "%s", device->pnp.bus_id);
474 	event->type = (TypeData & 0xFF000000) >> 24;
475 	event->data = (TypeData & 0x00FFFFFF);
476 
477 	KeAcquireSpinLock(&acpi_bus_event_lock, &OldIrql);
478 	list_add_tail(&event->node, &acpi_bus_event_list);
479 	KeReleaseSpinLock(&acpi_bus_event_lock, OldIrql);
480 
481 	KeSetEvent(&AcpiEventQueue, IO_NO_INCREMENT, FALSE);
482 }
483 
484 int
acpi_bus_generate_event(struct acpi_device * device,UINT8 type,int data)485 acpi_bus_generate_event (
486 	struct acpi_device	*device,
487 	UINT8			type,
488 	int			data)
489 {
490     ULONG_PTR TypeData = 0;
491 
492 	DPRINT("acpi_bus_generate_event\n");
493 
494 	if (!device)
495 		return_VALUE(AE_BAD_PARAMETER);
496 
497 	/* drop event on the floor if no one's listening */
498 	if (!event_is_open)
499 		return_VALUE(0);
500 
501     /* Data shouldn't even get near 24 bits */
502     ASSERT(!(data & 0xFF000000));
503 
504     TypeData = data;
505     TypeData |= type << 24;
506 
507 	KeInsertQueueDpc(&event_dpc, device, (PVOID)TypeData);
508 
509 	return_VALUE(0);
510 }
511 
512 int
acpi_bus_receive_event(struct acpi_bus_event * event)513 acpi_bus_receive_event (
514 	struct acpi_bus_event	*event)
515 {
516 //	unsigned long		flags = 0;
517 	struct acpi_bus_event	*entry = NULL;
518 	KIRQL OldIrql;
519 
520 	//DECLARE_WAITQUEUE(wait, current);
521 
522 	DPRINT("acpi_bus_receive_event\n");
523 
524 	if (!event)
525 		return AE_BAD_PARAMETER;
526 
527 	event_is_open++;
528 	KeWaitForSingleObject(&AcpiEventQueue,
529 			      Executive,
530 			      KernelMode,
531 			      FALSE,
532 			      NULL);
533 	event_is_open--;
534 	KeClearEvent(&AcpiEventQueue);
535 
536 	if (list_empty(&acpi_bus_event_list))
537 		return_VALUE(AE_NOT_FOUND);
538 
539 //	spin_lock_irqsave(&acpi_bus_event_lock, flags);
540 	KeAcquireSpinLock(&acpi_bus_event_lock, &OldIrql);
541 	entry = list_entry(acpi_bus_event_list.next, struct acpi_bus_event, node);
542 	if (entry)
543 		list_del(&entry->node);
544 	KeReleaseSpinLock(&acpi_bus_event_lock, OldIrql);
545 //	spin_unlock_irqrestore(&acpi_bus_event_lock, flags);
546 
547 	if (!entry)
548 		return_VALUE(AE_NOT_FOUND);
549 
550 	memcpy(event, entry, sizeof(struct acpi_bus_event));
551 
552 	ExFreePoolWithTag(entry, 'epcA');
553 	return_VALUE(0);
554 }
555 
556 
557 /* --------------------------------------------------------------------------
558                                Namespace Management
559    -------------------------------------------------------------------------- */
560 
561 
562 /**
563  * acpi_bus_walk
564  * -------------
565  * Used to walk the ACPI Bus's device namespace.  Can walk down (depth-first)
566  * or up.  Able to parse starting at any node in the namespace.  Note that a
567  * callback return value of -249 will terminate the walk.
568  *
569  * @start:	starting point
570  * callback:	function to call for every device encountered while parsing
571  * direction:	direction to parse (up or down)
572  * @data:	context for this search operation
573  */
574 static int
acpi_bus_walk(struct acpi_device * start,acpi_bus_walk_callback callback,int direction,void * data)575 acpi_bus_walk (
576 	struct acpi_device	*start,
577 	acpi_bus_walk_callback	callback,
578 	int			direction,
579 	void			*data)
580 {
581 	int			result = 0;
582 	int			level = 0;
583 	struct acpi_device	*device = NULL;
584 
585 	if (!start || !callback)
586 		return AE_BAD_PARAMETER;
587 
588 	device = start;
589 
590 	/*
591 	 * Parse Namespace
592 	 * ---------------
593 	 * Parse a given subtree (specified by start) in the given direction.
594 	 * Walking 'up' simply means that we execute the callback on leaf
595 	 * devices prior to their parents (useful for things like removing
596 	 * or powering down a subtree).
597 	 */
598 
599 	while (device) {
600 
601 		if (direction == WALK_DOWN)
602 			if (-249 == callback(device, level, data))
603 				break;
604 
605 		/* Depth First */
606 
607 		if (HAS_CHILDREN(device)) {
608 			device = NODE_TO_DEVICE(device->children.next);
609 			++level;
610 			continue;
611 		}
612 
613 		if (direction == WALK_UP)
614 			if (-249 == callback(device, level, data))
615 				break;
616 
617 		/* Now Breadth */
618 
619 		if (HAS_SIBLINGS(device)) {
620 			device = NODE_TO_DEVICE(device->node.next);
621 			continue;
622 		}
623 
624 		/* Scope Exhausted - Find Next */
625 
626 		while ((device = device->parent)) {
627 			--level;
628 			if (HAS_SIBLINGS(device)) {
629 				device = NODE_TO_DEVICE(device->node.next);
630 				break;
631 			}
632 		}
633 	}
634 
635 	if ((direction == WALK_UP) && (result == 0))
636 		callback(start, level, data);
637 
638 	return result;
639 }
640 
641 
642 /* --------------------------------------------------------------------------
643                              Notification Handling
644    -------------------------------------------------------------------------- */
645 
646 static void
acpi_bus_check_device(ACPI_HANDLE handle)647 acpi_bus_check_device (ACPI_HANDLE handle)
648 {
649 	struct acpi_device *device;
650 	ACPI_STATUS status = 0;
651 	struct acpi_device_status old_status;
652 
653 	if (acpi_bus_get_device(handle, &device))
654 		return;
655 	if (!device)
656 		return;
657 
658 	old_status = device->status;
659 
660 	/*
661 	 * Make sure this device's parent is present before we go about
662 	 * messing with the device.
663 	 */
664 	if (device->parent && !device->parent->status.present) {
665 		device->status = device->parent->status;
666 		return;
667 	}
668 
669 	status = acpi_bus_get_status(device);
670 	if (ACPI_FAILURE(status))
671 		return;
672 
673 	if (STRUCT_TO_INT(old_status) == STRUCT_TO_INT(device->status))
674 		return;
675 
676 
677 	/*
678 	 * Device Insertion/Removal
679 	 */
680 	if ((device->status.present) && !(old_status.present)) {
681 		DPRINT("Device insertion detected\n");
682 		/* TBD: Handle device insertion */
683 	}
684 	else if (!(device->status.present) && (old_status.present)) {
685 		DPRINT("Device removal detected\n");
686 		/* TBD: Handle device removal */
687 	}
688 
689 }
690 
691 
692 static void
acpi_bus_check_scope(ACPI_HANDLE handle)693 acpi_bus_check_scope (ACPI_HANDLE handle)
694 {
695 	/* Status Change? */
696 	acpi_bus_check_device(handle);
697 
698 	/*
699 	 * TBD: Enumerate child devices within this device's scope and
700 	 *       run acpi_bus_check_device()'s on them.
701 	 */
702 }
703 
704 
705 /**
706  * acpi_bus_notify
707  * ---------------
708  * Callback for all 'system-level' device notifications (values 0x00-0x7F).
709  */
710 static void
acpi_bus_notify(ACPI_HANDLE handle,UINT32 type,void * data)711 acpi_bus_notify (
712 	ACPI_HANDLE             handle,
713 	UINT32                     type,
714 	void                    *data)
715 {
716 	struct acpi_device *device = NULL;
717 	struct acpi_driver *driver;
718 
719 	DPRINT1("Notification %#02x to handle %p\n", type, handle);
720 
721 	//blocking_notifier_call_chain(&acpi_bus_notify_list,
722 	//	type, (void *)handle);
723 
724 	acpi_bus_get_device(handle, &device);
725 
726 	switch (type) {
727 
728 	case ACPI_NOTIFY_BUS_CHECK:
729 		DPRINT("Received BUS CHECK notification for device [%s]\n",
730 			device ? device->pnp.bus_id : "n/a");
731 		acpi_bus_check_scope(handle);
732 		/*
733 		 * TBD: We'll need to outsource certain events to non-ACPI
734 		 *	drivers via the device manager (device.c).
735 		 */
736 		break;
737 
738 	case ACPI_NOTIFY_DEVICE_CHECK:
739 		DPRINT("Received DEVICE CHECK notification for device [%s]\n",
740 			device ? device->pnp.bus_id : "n/a");
741 		acpi_bus_check_device(handle);
742 		/*
743 		 * TBD: We'll need to outsource certain events to non-ACPI
744 		 *	drivers via the device manager (device.c).
745 		 */
746 		break;
747 
748 	case ACPI_NOTIFY_DEVICE_WAKE:
749 		DPRINT("Received DEVICE WAKE notification for device [%s]\n",
750 			device ? device->pnp.bus_id : "n/a");
751 		acpi_bus_check_device(handle);
752 		/*
753 		 * TBD: We'll need to outsource certain events to non-ACPI
754 		 *      drivers via the device manager (device.c).
755 		 */
756 		break;
757 
758 	case ACPI_NOTIFY_EJECT_REQUEST:
759 		DPRINT1("Received EJECT REQUEST notification for device [%s]\n",
760 			device ? device->pnp.bus_id : "n/a");
761 		/* TBD */
762 		break;
763 
764 	case ACPI_NOTIFY_DEVICE_CHECK_LIGHT:
765 		DPRINT1("Received DEVICE CHECK LIGHT notification for device [%s]\n",
766 			device ? device->pnp.bus_id : "n/a");
767 		/* TBD: Exactly what does 'light' mean? */
768 		break;
769 
770 	case ACPI_NOTIFY_FREQUENCY_MISMATCH:
771 		DPRINT1("Received FREQUENCY MISMATCH notification for device [%s]\n",
772 			device ? device->pnp.bus_id : "n/a");
773 		/* TBD */
774 		break;
775 
776 	case ACPI_NOTIFY_BUS_MODE_MISMATCH:
777 		DPRINT1("Received BUS MODE MISMATCH notification for device [%s]\n",
778 			device ? device->pnp.bus_id : "n/a");
779 		/* TBD */
780 		break;
781 
782 	case ACPI_NOTIFY_POWER_FAULT:
783 		DPRINT1("Received POWER FAULT notification for device [%s]\n",
784 			device ? device->pnp.bus_id : "n/a");
785 		/* TBD */
786 		break;
787 
788 	default:
789 		DPRINT1("Received unknown/unsupported notification [%08x] for device [%s]\n",
790 			type, device ? device->pnp.bus_id : "n/a");
791 		break;
792 	}
793 
794 	if (device) {
795 		driver = device->driver;
796 		if (driver && driver->ops.notify &&
797 		    (driver->flags & ACPI_DRIVER_ALL_NOTIFY_EVENTS))
798 			driver->ops.notify(device, type);
799 	}
800 }
801 
802 
803 /* --------------------------------------------------------------------------
804                                  Driver Management
805    -------------------------------------------------------------------------- */
806 
807 
808 static LIST_HEAD(acpi_bus_drivers);
809 //static DECLARE_MUTEX(acpi_bus_drivers_lock);
810 static FAST_MUTEX acpi_bus_drivers_lock;
811 
812 
813 /**
814  * acpi_bus_match
815  * --------------
816  * Checks the device's hardware (_HID) or compatible (_CID) ids to see if it
817  * matches the specified driver's criteria.
818  */
819 static int
acpi_bus_match(struct acpi_device * device,struct acpi_driver * driver)820 acpi_bus_match (
821 	struct acpi_device	*device,
822 	struct acpi_driver	*driver)
823 {
824 	int error = 0;
825 
826 	if (device->flags.hardware_id)
827 		if (strstr(driver->ids, device->pnp.hardware_id))
828 			goto Done;
829 
830 	if (device->flags.compatible_ids) {
831 		ACPI_PNP_DEVICE_ID_LIST *cid_list = device->pnp.cid_list;
832 		int i;
833 
834 		/* compare multiple _CID entries against driver ids */
835 		for (i = 0; i < cid_list->Count; i++)
836 		{
837 			if (strstr(driver->ids, cid_list->Ids[i].String))
838 				goto Done;
839 		}
840 	}
841 	error = -2;
842 
843  Done:
844 
845 	return error;
846 }
847 
848 
849 /**
850  * acpi_bus_driver_init
851  * --------------------
852  * Used to initialize a device via its device driver.  Called whenever a
853  * driver is bound to a device.  Invokes the driver's add() and start() ops.
854  */
855 static int
acpi_bus_driver_init(struct acpi_device * device,struct acpi_driver * driver)856 acpi_bus_driver_init (
857 	struct acpi_device	*device,
858 	struct acpi_driver	*driver)
859 {
860 	int			result = 0;
861 
862 	if (!device || !driver)
863 		return_VALUE(AE_BAD_PARAMETER);
864 
865 	if (!driver->ops.add)
866 		return_VALUE(-38);
867 
868 	result = driver->ops.add(device);
869 	if (result) {
870 		device->driver = NULL;
871 		//acpi_driver_data(device) = NULL;
872 		return_VALUE(result);
873 	}
874 
875 	device->driver = driver;
876 
877 	/*
878 	 * TBD - Configuration Management: Assign resources to device based
879 	 * upon possible configuration and currently allocated resources.
880 	 */
881 
882 	if (driver->ops.start) {
883 		result = driver->ops.start(device);
884 		if (result && driver->ops.remove)
885 			driver->ops.remove(device, ACPI_BUS_REMOVAL_NORMAL);
886 		return_VALUE(result);
887 	}
888 
889 	DPRINT("Driver successfully bound to device\n");
890 
891 	if (driver->ops.scan) {
892 		driver->ops.scan(device);
893 	}
894 
895 	return_VALUE(0);
896 }
897 
898 
899 /**
900  * acpi_bus_attach
901  * -------------
902  * Callback for acpi_bus_walk() used to find devices that match a specific
903  * driver's criteria and then attach the driver.
904  */
905 static int
acpi_bus_attach(struct acpi_device * device,int level,void * data)906 acpi_bus_attach (
907 	struct acpi_device	*device,
908 	int			level,
909 	void			*data)
910 {
911 	int			result = 0;
912 	struct acpi_driver	*driver = NULL;
913 
914 	if (!device || !data)
915 		return_VALUE(AE_BAD_PARAMETER);
916 
917 	driver = (struct acpi_driver *) data;
918 
919 	if (device->driver)
920 		return_VALUE(-9);
921 
922 	if (!device->status.present)
923 		return_VALUE(AE_NOT_FOUND);
924 
925 	result = acpi_bus_match(device, driver);
926 	if (result)
927 		return_VALUE(result);
928 
929 	DPRINT("Found driver [%s] for device [%s]\n",
930 		driver->name, device->pnp.bus_id);
931 
932 	result = acpi_bus_driver_init(device, driver);
933 	if (result)
934 		return_VALUE(result);
935 
936 	down(&acpi_bus_drivers_lock);
937 	++driver->references;
938 	up(&acpi_bus_drivers_lock);
939 
940 	return_VALUE(0);
941 }
942 
943 
944 /**
945  * acpi_bus_unattach
946  * -----------------
947  * Callback for acpi_bus_walk() used to find devices that match a specific
948  * driver's criteria and unattach the driver.
949  */
950 static int
acpi_bus_unattach(struct acpi_device * device,int level,void * data)951 acpi_bus_unattach (
952 	struct acpi_device	*device,
953 	int			level,
954 	void			*data)
955 {
956 	int			result = 0;
957 	struct acpi_driver	*driver = (struct acpi_driver *) data;
958 
959 	if (!device || !driver)
960 		return_VALUE(AE_BAD_PARAMETER);
961 
962 	if (device->driver != driver)
963 		return_VALUE(-6);
964 
965 	if (!driver->ops.remove)
966 		return_VALUE(-23);
967 
968 	result = driver->ops.remove(device, ACPI_BUS_REMOVAL_NORMAL);
969 	if (result)
970 		return_VALUE(result);
971 
972 	device->driver = NULL;
973 	acpi_driver_data(device) = NULL;
974 
975 	down(&acpi_bus_drivers_lock);
976 	driver->references--;
977 	up(&acpi_bus_drivers_lock);
978 
979 	return_VALUE(0);
980 }
981 
982 
983 /**
984  * acpi_bus_find_driver
985  * --------------------
986  * Parses the list of registered drivers looking for a driver applicable for
987  * the specified device.
988  */
989 static int
acpi_bus_find_driver(struct acpi_device * device)990 acpi_bus_find_driver (
991 	struct acpi_device	*device)
992 {
993 	int			result = AE_NOT_FOUND;
994 	struct list_head	*entry = NULL;
995 	struct acpi_driver	*driver = NULL;
996 
997 	if (!device || device->driver)
998 		return_VALUE(AE_BAD_PARAMETER);
999 
1000 	down(&acpi_bus_drivers_lock);
1001 
1002 	list_for_each(entry, &acpi_bus_drivers) {
1003 
1004 		driver = list_entry(entry, struct acpi_driver, node);
1005 
1006 		if (acpi_bus_match(device, driver))
1007 			continue;
1008 
1009 		result = acpi_bus_driver_init(device, driver);
1010 		if (!result)
1011 			++driver->references;
1012 
1013 		break;
1014 	}
1015 
1016 	up(&acpi_bus_drivers_lock);
1017 
1018 	return_VALUE(result);
1019 }
1020 
1021 
1022 /**
1023  * acpi_bus_register_driver
1024  * ------------------------
1025  * Registers a driver with the ACPI bus.  Searches the namespace for all
1026  * devices that match the driver's criteria and binds.
1027  */
1028 int
acpi_bus_register_driver(struct acpi_driver * driver)1029 acpi_bus_register_driver (
1030 	struct acpi_driver	*driver)
1031 {
1032 	if (!driver)
1033 		return_VALUE(AE_BAD_PARAMETER);
1034 
1035 	//if (acpi_disabled)
1036 	//	return_VALUE(AE_NOT_FOUND);
1037 
1038 	down(&acpi_bus_drivers_lock);
1039 	list_add_tail(&driver->node, &acpi_bus_drivers);
1040 	up(&acpi_bus_drivers_lock);
1041 
1042 	acpi_bus_walk(acpi_root, acpi_bus_attach,
1043 		WALK_DOWN, driver);
1044 
1045 	return_VALUE(driver->references);
1046 }
1047 
1048 
1049 /**
1050  * acpi_bus_unregister_driver
1051  * --------------------------
1052  * Unregisters a driver with the ACPI bus.  Searches the namespace for all
1053  * devices that match the driver's criteria and unbinds.
1054  */
1055 void
acpi_bus_unregister_driver(struct acpi_driver * driver)1056 acpi_bus_unregister_driver (
1057 	struct acpi_driver	*driver)
1058 {
1059 	if (!driver)
1060 		return;
1061 
1062 	acpi_bus_walk(acpi_root, acpi_bus_unattach, WALK_UP, driver);
1063 
1064 	if (driver->references)
1065 		return;
1066 
1067 	down(&acpi_bus_drivers_lock);
1068 	list_del(&driver->node);
1069 	up(&acpi_bus_drivers_lock);
1070 
1071 	return;
1072 }
1073 
1074 
1075 /* --------------------------------------------------------------------------
1076                                  Device Enumeration
1077    -------------------------------------------------------------------------- */
1078 
1079 static int
acpi_bus_get_flags(struct acpi_device * device)1080 acpi_bus_get_flags (
1081 	struct acpi_device	*device)
1082 {
1083 	ACPI_STATUS		status = AE_OK;
1084 	ACPI_HANDLE		temp = NULL;
1085 
1086 	/* Presence of _STA indicates 'dynamic_status' */
1087 	status = AcpiGetHandle(device->handle, "_STA", &temp);
1088 	if (ACPI_SUCCESS(status))
1089 		device->flags.dynamic_status = 1;
1090 
1091 	/* Presence of _CID indicates 'compatible_ids' */
1092 	status = AcpiGetHandle(device->handle, "_CID", &temp);
1093 	if (ACPI_SUCCESS(status))
1094 		device->flags.compatible_ids = 1;
1095 
1096 	/* Presence of _RMV indicates 'removable' */
1097 	status = AcpiGetHandle(device->handle, "_RMV", &temp);
1098 	if (ACPI_SUCCESS(status))
1099 		device->flags.removable = 1;
1100 
1101 	/* Presence of _EJD|_EJ0 indicates 'ejectable' */
1102 	status = AcpiGetHandle(device->handle, "_EJD", &temp);
1103 	if (ACPI_SUCCESS(status))
1104 		device->flags.ejectable = 1;
1105 	else {
1106 		status = AcpiGetHandle(device->handle, "_EJ0", &temp);
1107 		if (ACPI_SUCCESS(status))
1108 			device->flags.ejectable = 1;
1109 	}
1110 
1111 	/* Presence of _LCK indicates 'lockable' */
1112 	status = AcpiGetHandle(device->handle, "_LCK", &temp);
1113 	if (ACPI_SUCCESS(status))
1114 		device->flags.lockable = 1;
1115 
1116 	/* Presence of _PS0|_PR0 indicates 'power manageable' */
1117 	status = AcpiGetHandle(device->handle, "_PS0", &temp);
1118 	if (ACPI_FAILURE(status))
1119 		status = AcpiGetHandle(device->handle, "_PR0", &temp);
1120 	if (ACPI_SUCCESS(status))
1121 		device->flags.power_manageable = 1;
1122 
1123 	/* TBD: Performance management */
1124 
1125 	return_VALUE(0);
1126 }
1127 
1128 
1129 int
acpi_bus_add(struct acpi_device ** child,struct acpi_device * parent,ACPI_HANDLE handle,int type)1130 acpi_bus_add (
1131 	struct acpi_device	**child,
1132 	struct acpi_device	*parent,
1133 	ACPI_HANDLE		handle,
1134 	int			type)
1135 {
1136 	int			result = 0;
1137 	ACPI_STATUS		status = AE_OK;
1138 	struct acpi_device	*device = NULL;
1139 	char			bus_id[5] = {'?',0};
1140 	ACPI_BUFFER	buffer;
1141 	ACPI_DEVICE_INFO	*info = NULL;
1142 	char			*hid = NULL;
1143 	char			*uid = NULL;
1144 	ACPI_PNP_DEVICE_ID_LIST *cid_list = NULL;
1145 	int			i = 0;
1146 	acpi_unique_id		static_uid_buffer;
1147 
1148 	if (!child)
1149 		return_VALUE(AE_BAD_PARAMETER);
1150 
1151 	device = ExAllocatePoolWithTag(NonPagedPool,sizeof(struct acpi_device), 'DpcA');
1152 	if (!device) {
1153 		DPRINT1("Memory allocation error\n");
1154 		return_VALUE(-12);
1155 	}
1156 	memset(device, 0, sizeof(struct acpi_device));
1157 
1158 	device->handle = handle;
1159 	device->parent = parent;
1160 
1161 	/*
1162 	 * Bus ID
1163 	 * ------
1164 	 * The device's Bus ID is simply the object name.
1165 	 * TBD: Shouldn't this value be unique (within the ACPI namespace)?
1166 	 */
1167 	switch (type) {
1168 	case ACPI_BUS_TYPE_SYSTEM:
1169 		snprintf(device->pnp.bus_id, sizeof(device->pnp.bus_id), "%s", "ACPI");
1170 		break;
1171 	case ACPI_BUS_TYPE_POWER_BUTTONF:
1172 	case ACPI_BUS_TYPE_POWER_BUTTON:
1173 		snprintf(device->pnp.bus_id, sizeof(device->pnp.bus_id), "%s", "PWRF");
1174 		break;
1175 	case ACPI_BUS_TYPE_SLEEP_BUTTONF:
1176 	case ACPI_BUS_TYPE_SLEEP_BUTTON:
1177 		snprintf(device->pnp.bus_id, sizeof(device->pnp.bus_id), "%s", "SLPF");
1178 		break;
1179 	default:
1180 		buffer.Length = sizeof(bus_id);
1181 		buffer.Pointer = bus_id;
1182 		AcpiGetName(handle, ACPI_SINGLE_NAME, &buffer);
1183 
1184 
1185 		/* Clean up trailing underscores (if any) */
1186 		for (i = 3; i > 1; i--) {
1187 			if (bus_id[i] == '_')
1188 				bus_id[i] = '\0';
1189 			else
1190 				break;
1191 		}
1192 		snprintf(device->pnp.bus_id, sizeof(device->pnp.bus_id), "%s", bus_id);
1193 		buffer.Pointer = NULL;
1194 
1195 		break;
1196 	}
1197 
1198 	/*
1199 	 * Flags
1200 	 * -----
1201 	 * Get prior to calling acpi_bus_get_status() so we know whether
1202 	 * or not _STA is present.  Note that we only look for object
1203 	 * handles -- cannot evaluate objects until we know the device is
1204 	 * present and properly initialized.
1205 	 */
1206 	result = acpi_bus_get_flags(device);
1207 	if (result)
1208 		goto end;
1209 
1210 	/*
1211 	 * Status
1212 	 * ------
1213 	 * See if the device is present.  We always assume that non-Device()
1214 	 * objects (e.g. thermal zones, power resources, processors, etc.) are
1215 	 * present, functioning, etc. (at least when parent object is present).
1216 	 * Note that _STA has a different meaning for some objects (e.g.
1217 	 * power resources) so we need to be careful how we use it.
1218 	 */
1219 	switch (type) {
1220 	case ACPI_BUS_TYPE_DEVICE:
1221 		result = acpi_bus_get_status(device);
1222 		if (result)
1223 			goto end;
1224 		break;
1225 	default:
1226 		STRUCT_TO_INT(device->status) = 0x0F;
1227 		break;
1228 	}
1229 	if (!device->status.present) {
1230 		result = -2;
1231 		goto end;
1232 	}
1233 
1234 	/*
1235 	 * Initialize Device
1236 	 * -----------------
1237 	 * TBD: Synch with Core's enumeration/initialization process.
1238 	 */
1239 
1240 	/*
1241 	 * Hardware ID, Unique ID, & Bus Address
1242 	 * -------------------------------------
1243 	 */
1244 	switch (type) {
1245 	case ACPI_BUS_TYPE_DEVICE:
1246 		status = AcpiGetObjectInfo(handle,&info);
1247 		if (ACPI_FAILURE(status)) {
1248 			ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
1249 				"Error reading device info\n"));
1250 			result = AE_NOT_FOUND;
1251 			info = NULL;
1252 			goto end;
1253 		}
1254 		if (info->Valid & ACPI_VALID_HID)
1255 			hid = info->HardwareId.String;
1256 		if (info->Valid & ACPI_VALID_UID)
1257 			uid = info->UniqueId.String;
1258 		if (info->Valid & ACPI_VALID_CID) {
1259 			cid_list = &info->CompatibleIdList;
1260 			device->pnp.cid_list = ExAllocatePoolWithTag(NonPagedPool,cid_list->ListSize, 'DpcA');
1261 			if (device->pnp.cid_list) {
1262 				char *p = (char *)&device->pnp.cid_list->Ids[cid_list->Count];
1263 				device->pnp.cid_list->Count = cid_list->Count;
1264 				device->pnp.cid_list->ListSize = cid_list->ListSize;
1265 				for (i = 0; i < cid_list->Count; i++) {
1266 					device->pnp.cid_list->Ids[i].Length = cid_list->Ids[i].Length;
1267 					device->pnp.cid_list->Ids[i].String = p;
1268 					ASSERT(p + cid_list->Ids[i].Length <= (char *)device->pnp.cid_list + cid_list->ListSize);
1269 					memcpy(device->pnp.cid_list->Ids[i].String,
1270 						cid_list->Ids[i].String, cid_list->Ids[i].Length);
1271 					p += cid_list->Ids[i].Length;
1272 				}
1273 			}
1274 			else
1275 				DPRINT("Memory allocation error\n");
1276 		}
1277 		if (info->Valid & ACPI_VALID_ADR) {
1278 			device->pnp.bus_address = info->Address;
1279 			device->flags.bus_address = 1;
1280 		}
1281 		break;
1282 	case ACPI_BUS_TYPE_POWER:
1283 		hid = ACPI_POWER_HID;
1284         uid = static_uid_buffer;
1285 		snprintf(uid, sizeof(static_uid_buffer), "%d", (PowerDeviceCount++));
1286 		break;
1287 	case ACPI_BUS_TYPE_PROCESSOR:
1288 		hid = ACPI_PROCESSOR_HID;
1289 		uid = static_uid_buffer;
1290 		snprintf(uid, sizeof(static_uid_buffer), "_%d", (ProcessorCount++));
1291 		break;
1292 	case ACPI_BUS_TYPE_SYSTEM:
1293 		hid = ACPI_SYSTEM_HID;
1294 		break;
1295 	case ACPI_BUS_TYPE_THERMAL:
1296 		hid = ACPI_THERMAL_HID;
1297         uid = static_uid_buffer;
1298 		snprintf(uid, sizeof(static_uid_buffer), "%d", (ThermalZoneCount++));
1299 		break;
1300 	case ACPI_BUS_TYPE_POWER_BUTTON:
1301 		hid = ACPI_BUTTON_HID_POWER;
1302         uid = static_uid_buffer;
1303 		snprintf(uid, sizeof(static_uid_buffer), "%d", (PowerButtonCount++));
1304 		break;
1305 	case ACPI_BUS_TYPE_POWER_BUTTONF:
1306 		hid = ACPI_BUTTON_HID_POWERF;
1307         uid = static_uid_buffer;
1308 		snprintf(uid, sizeof(static_uid_buffer), "%d", (FixedPowerButtonCount++));
1309 		break;
1310 	case ACPI_BUS_TYPE_SLEEP_BUTTON:
1311 		hid = ACPI_BUTTON_HID_SLEEP;
1312         uid = static_uid_buffer;
1313 		snprintf(uid, sizeof(static_uid_buffer), "%d", (SleepButtonCount++));
1314 		break;
1315 	case ACPI_BUS_TYPE_SLEEP_BUTTONF:
1316 		hid = ACPI_BUTTON_HID_SLEEPF;
1317         uid = static_uid_buffer;
1318 		snprintf(uid, sizeof(static_uid_buffer), "%d", (FixedSleepButtonCount++));
1319 		break;
1320 	}
1321 
1322 	/*
1323 	 * \_SB
1324 	 * ----
1325 	 * Fix for the system root bus device -- the only root-level device.
1326 	 */
1327 	if (((ACPI_HANDLE)parent == ACPI_ROOT_OBJECT) && (type == ACPI_BUS_TYPE_DEVICE)) {
1328 		hid = ACPI_BUS_HID;
1329 		snprintf(device->pnp.device_name, sizeof(device->pnp.device_name), "%s", ACPI_BUS_DEVICE_NAME);
1330 		snprintf(device->pnp.device_class, sizeof(device->pnp.device_class), "%s", ACPI_BUS_CLASS);
1331 	}
1332 
1333 	if (hid) {
1334         device->pnp.hardware_id = ExAllocatePoolWithTag(NonPagedPool, strlen(hid) + 1, 'DpcA');
1335         if (device->pnp.hardware_id) {
1336             snprintf(device->pnp.hardware_id, strlen(hid) + 1, "%s", hid);
1337             device->flags.hardware_id = 1;
1338         }
1339 	}
1340 	if (uid) {
1341 		snprintf(device->pnp.unique_id, sizeof(device->pnp.unique_id), "%s", uid);
1342 		device->flags.unique_id = 1;
1343 	}
1344 
1345 	/*
1346 	 * If we called get_object_info, we now are finished with the buffer,
1347 	 * so we can free it.
1348 	 */
1349 	//if (buffer.Pointer)
1350 		//AcpiOsFree(buffer.Pointer);
1351 
1352 	/*
1353 	 * Power Management
1354 	 * ----------------
1355 	 */
1356 	if (device->flags.power_manageable) {
1357 		result = acpi_bus_get_power_flags(device);
1358 		if (result)
1359 			goto end;
1360 	}
1361 
1362 	/*
1363 	 * Performance Management
1364 	 * ----------------------
1365 	 */
1366 	if (device->flags.performance_manageable) {
1367 		result = acpi_bus_get_perf_flags(device);
1368 		if (result)
1369 			goto end;
1370 	}
1371 
1372 	/*
1373 	 * Context
1374 	 * -------
1375 	 * Attach this 'struct acpi_device' to the ACPI object.  This makes
1376 	 * resolutions from handle->device very efficient.  Note that we need
1377 	 * to be careful with fixed-feature devices as they all attach to the
1378 	 * root object.
1379 	 */
1380 	switch (type) {
1381 	case ACPI_BUS_TYPE_POWER_BUTTON:
1382 	case ACPI_BUS_TYPE_POWER_BUTTONF:
1383 	case ACPI_BUS_TYPE_SLEEP_BUTTON:
1384 	case ACPI_BUS_TYPE_SLEEP_BUTTONF:
1385 		break;
1386 	default:
1387 		status = AcpiAttachData(device->handle,
1388 			acpi_bus_data_handler, device);
1389 		break;
1390 	}
1391 	if (ACPI_FAILURE(status)) {
1392 		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
1393 			"Error attaching device data\n"));
1394 		result = AE_NOT_FOUND;
1395 		goto end;
1396 	}
1397 
1398 	/*
1399 	 * Linkage
1400 	 * -------
1401 	 * Link this device to its parent and siblings.
1402 	 */
1403 	INIT_LIST_HEAD(&device->children);
1404 	if (!device->parent)
1405 		INIT_LIST_HEAD(&device->node);
1406 	else
1407 		list_add_tail(&device->node, &device->parent->children);
1408 
1409 	/*
1410 	 * Global Device Hierarchy:
1411 	 * ------------------------
1412 	 * Register this device with the global device hierarchy.
1413 	 */
1414 	acpi_device_register(device, parent);
1415 
1416 	/*
1417 	 * Bind _ADR-Based Devices
1418 	 * -----------------------
1419 	 * If there's a a bus address (_ADR) then we utilize the parent's
1420 	 * 'bind' function (if exists) to bind the ACPI- and natively-
1421 	 * enumerated device representations.
1422 	 */
1423 	if (device->flags.bus_address) {
1424 		if (device->parent && device->parent->ops.bind)
1425 			device->parent->ops.bind(device);
1426 	}
1427 
1428 	/*
1429 	 * Locate & Attach Driver
1430 	 * ----------------------
1431 	 * If there's a hardware id (_HID) or compatible ids (_CID) we check
1432 	 * to see if there's a driver installed for this kind of device.  Note
1433 	 * that drivers can install before or after a device is enumerated.
1434 	 *
1435 	 * TBD: Assumes LDM provides driver hot-plug capability.
1436 	 */
1437 	if (device->flags.hardware_id || device->flags.compatible_ids)
1438 		acpi_bus_find_driver(device);
1439 
1440 end:
1441 	if (info != NULL)
1442 		ACPI_FREE(info);
1443 	if (result) {
1444 		if (device->pnp.cid_list) {
1445 			ExFreePoolWithTag(device->pnp.cid_list, 'DpcA');
1446 		}
1447         if (device->pnp.hardware_id) {
1448             ExFreePoolWithTag(device->pnp.hardware_id, 'DpcA');
1449         }
1450 		ExFreePoolWithTag(device, 'DpcA');
1451 		return_VALUE(result);
1452 	}
1453 	*child = device;
1454 
1455 	return_VALUE(0);
1456 }
1457 
1458 
1459 static int
acpi_bus_remove(struct acpi_device * device,int type)1460 acpi_bus_remove (
1461 	struct acpi_device	*device,
1462 	int			type)
1463 {
1464 
1465 	if (!device)
1466 		return_VALUE(AE_NOT_FOUND);
1467 
1468 	acpi_device_unregister(device);
1469 
1470 	if (device->pnp.cid_list)
1471 		ExFreePoolWithTag(device->pnp.cid_list, 'DpcA');
1472 
1473 	if (device->pnp.hardware_id)
1474 		ExFreePoolWithTag(device->pnp.hardware_id, 'DpcA');
1475 
1476 	if (device)
1477 		ExFreePoolWithTag(device, 'DpcA');
1478 
1479 	return_VALUE(0);
1480 }
1481 
1482 
1483 int
acpi_bus_scan(struct acpi_device * start)1484 acpi_bus_scan (
1485 	struct acpi_device	*start)
1486 {
1487 	ACPI_STATUS		status = AE_OK;
1488 	struct acpi_device	*parent = NULL;
1489 	struct acpi_device	*child = NULL;
1490 	ACPI_HANDLE		phandle = 0;
1491 	ACPI_HANDLE		chandle = 0;
1492 	ACPI_OBJECT_TYPE	type = 0;
1493 	UINT32			level = 1;
1494 
1495 	if (!start)
1496 		return_VALUE(AE_BAD_PARAMETER);
1497 
1498 	parent = start;
1499 	phandle = start->handle;
1500 
1501 	/*
1502 	 * Parse through the ACPI namespace, identify all 'devices', and
1503 	 * create a new 'struct acpi_device' for each.
1504 	 */
1505 	while ((level > 0) && parent) {
1506 
1507 		status = AcpiGetNextObject(ACPI_TYPE_ANY, phandle,
1508 			chandle, &chandle);
1509 
1510 		/*
1511 		 * If this scope is exhausted then move our way back up.
1512 		 */
1513 		if (ACPI_FAILURE(status)) {
1514 			level--;
1515 			chandle = phandle;
1516 			AcpiGetParent(phandle, &phandle);
1517 			if (parent->parent)
1518 				parent = parent->parent;
1519 			continue;
1520 		}
1521 
1522 		status = AcpiGetType(chandle, &type);
1523 		if (ACPI_FAILURE(status))
1524 			continue;
1525 
1526 		/*
1527 		 * If this is a scope object then parse it (depth-first).
1528 		 */
1529 		if (type == ACPI_TYPE_LOCAL_SCOPE) {
1530 			level++;
1531 			phandle = chandle;
1532 			chandle = 0;
1533 			continue;
1534 		}
1535 
1536 		/*
1537 		 * We're only interested in objects that we consider 'devices'.
1538 		 */
1539 		switch (type) {
1540 		case ACPI_TYPE_DEVICE:
1541 			type = ACPI_BUS_TYPE_DEVICE;
1542 			break;
1543 		case ACPI_TYPE_PROCESSOR:
1544 			type = ACPI_BUS_TYPE_PROCESSOR;
1545 			break;
1546 		case ACPI_TYPE_THERMAL:
1547 			type = ACPI_BUS_TYPE_THERMAL;
1548 			break;
1549 		case ACPI_TYPE_POWER:
1550 			type = ACPI_BUS_TYPE_POWER;
1551 			break;
1552 		default:
1553 			continue;
1554 		}
1555 
1556 		status = acpi_bus_add(&child, parent, chandle, type);
1557 		if (ACPI_FAILURE(status))
1558 			continue;
1559 
1560 		/*
1561 		 * If the device is present, enabled, and functioning then
1562 		 * parse its scope (depth-first).  Note that we need to
1563 		 * represent absent devices to facilitate PnP notifications
1564 		 * -- but only the subtree head (not all of its children,
1565 		 * which will be enumerated when the parent is inserted).
1566 		 *
1567 		 * TBD: Need notifications and other detection mechanisms
1568 		 *	in place before we can fully implement this.
1569 		 */
1570 		if (child->status.present) {
1571 			status = AcpiGetNextObject(ACPI_TYPE_ANY, chandle,
1572 				0, NULL);
1573 			if (ACPI_SUCCESS(status)) {
1574 				level++;
1575 				phandle = chandle;
1576 				chandle = 0;
1577 				parent = child;
1578 			}
1579 		}
1580 	}
1581 
1582 	return_VALUE(0);
1583 }
1584 
1585 
1586 static int
acpi_bus_scan_fixed(struct acpi_device * root)1587 acpi_bus_scan_fixed (
1588 	struct acpi_device	*root)
1589 {
1590 	int			result = 0;
1591 	struct acpi_device	*device = NULL;
1592 
1593 	if (!root)
1594 		return_VALUE(AE_NOT_FOUND);
1595 
1596 	/* If ACPI_FADT_POWER_BUTTON is set, then a control
1597 	 * method power button is present. Otherwise, a fixed
1598 	 * power button is present.
1599 	 */
1600 	if (AcpiGbl_FADT.Flags & ACPI_FADT_POWER_BUTTON)
1601 		result = acpi_bus_add(&device, acpi_root,
1602 			NULL, ACPI_BUS_TYPE_POWER_BUTTON);
1603 	else
1604 	{
1605 		/* Enable the fixed power button so we get notified if it is pressed */
1606 		AcpiWriteBitRegister(ACPI_BITREG_POWER_BUTTON_ENABLE, 1);
1607 
1608 		result = acpi_bus_add(&device, acpi_root,
1609 			NULL, ACPI_BUS_TYPE_POWER_BUTTONF);
1610 	}
1611 
1612 	/* This one is a bit more complicated and we do it wrong
1613 	 * right now. If ACPI_FADT_SLEEP_BUTTON is set but no
1614 	 * device object is present then no sleep button is present, but
1615 	 * if the flags is clear and there is no device object then it is
1616 	 * a fixed sleep button. If the flag is set and there is a device object
1617 	 * the we have a control method button just like above.
1618 	 */
1619 	if (AcpiGbl_FADT.Flags & ACPI_FADT_SLEEP_BUTTON)
1620 		result = acpi_bus_add(&device, acpi_root,
1621 			NULL, ACPI_BUS_TYPE_SLEEP_BUTTON);
1622 	else
1623 	{
1624 		/* Enable the fixed sleep button so we get notified if it is pressed */
1625 		AcpiWriteBitRegister(ACPI_BITREG_SLEEP_BUTTON_ENABLE, 1);
1626 
1627 		result = acpi_bus_add(&device, acpi_root,
1628 			NULL, ACPI_BUS_TYPE_SLEEP_BUTTONF);
1629 	}
1630 
1631 	return_VALUE(result);
1632 }
1633 
1634 
1635 /* --------------------------------------------------------------------------
1636                              Initialization/Cleanup
1637    -------------------------------------------------------------------------- */
1638 
1639 int
acpi_bus_init(void)1640 acpi_bus_init (void)
1641 {
1642 	int			result = 0;
1643 	ACPI_STATUS		status = AE_OK;
1644 
1645 	DPRINT("acpi_bus_init\n");
1646 
1647         KeInitializeDpc(&event_dpc, acpi_bus_generate_event_dpc, NULL);
1648 
1649 	status = AcpiEnableSubsystem(ACPI_FULL_INITIALIZATION);
1650 	if (ACPI_FAILURE(status)) {
1651 		DPRINT1("Unable to start the ACPI Interpreter\n");
1652 		goto error1;
1653 	}
1654 
1655 	/*
1656 	 * ACPI 2.0 requires the EC driver to be loaded and work before
1657 	 * the EC device is found in the namespace. This is accomplished
1658 	 * by looking for the ECDT table, and getting the EC parameters out
1659 	 * of that.
1660 	 */
1661 	//result = acpi_ec_ecdt_probe();
1662 	/* Ignore result. Not having an ECDT is not fatal. */
1663 
1664 	status = AcpiInitializeObjects(ACPI_FULL_INITIALIZATION);
1665 	if (ACPI_FAILURE(status)) {
1666 		DPRINT1("Unable to initialize ACPI objects\n");
1667 		goto error1;
1668 	}
1669 
1670 	/*
1671 	 * Maybe EC region is required at bus_scan/acpi_get_devices. So it
1672 	 * is necessary to enable it as early as possible.
1673 	 */
1674 	//acpi_boot_ec_enable();
1675 
1676 	/* Initialize sleep structures */
1677 	//acpi_sleep_init();
1678 
1679 	/*
1680 	 * Register the for all standard device notifications.
1681 	 */
1682 	status = AcpiInstallNotifyHandler(ACPI_ROOT_OBJECT, ACPI_SYSTEM_NOTIFY, acpi_bus_notify, NULL);
1683 	if (ACPI_FAILURE(status)) {
1684 		DPRINT1("Unable to register for device notifications\n");
1685 		result = AE_NOT_FOUND;
1686 		goto error1;
1687 	}
1688 
1689 	/*
1690 	 * Create the root device in the bus's device tree
1691 	 */
1692 	result = acpi_bus_add(&acpi_root, NULL, ACPI_ROOT_OBJECT,
1693 		ACPI_BUS_TYPE_SYSTEM);
1694 	if (result)
1695 		goto error2;
1696 
1697 
1698 	/*
1699 	 * Enumerate devices in the ACPI namespace.
1700 	 */
1701 	result = acpi_bus_scan_fixed(acpi_root);
1702 	if (result)
1703 		DPRINT1("acpi_bus_scan_fixed failed\n");
1704 	result = acpi_bus_scan(acpi_root);
1705 	if (result)
1706 		DPRINT1("acpi_bus_scan failed\n");
1707 
1708 	return_VALUE(0);
1709 
1710 	/* Mimic structured exception handling */
1711 error2:
1712 	AcpiRemoveNotifyHandler(ACPI_ROOT_OBJECT,
1713 		ACPI_SYSTEM_NOTIFY, acpi_bus_notify);
1714 error1:
1715 	AcpiTerminate();
1716 	return_VALUE(AE_NOT_FOUND);
1717 }
1718 
1719 static void
acpi_bus_exit(void)1720 acpi_bus_exit (void)
1721 {
1722 	ACPI_STATUS		status = AE_OK;
1723 
1724 	DPRINT1("acpi_bus_exit\n");
1725 
1726 	status = AcpiRemoveNotifyHandler(ACPI_ROOT_OBJECT,
1727 		ACPI_SYSTEM_NOTIFY, acpi_bus_notify);
1728 	if (ACPI_FAILURE(status))
1729 		DPRINT1("Error removing notify handler\n");
1730 
1731 #ifdef CONFIG_ACPI_PCI
1732 	acpi_pci_root_exit();
1733 	acpi_pci_link_exit();
1734 #endif
1735 #ifdef CONFIG_ACPI_EC
1736 	acpi_ec_exit();
1737 #endif
1738 	//acpi_power_exit();
1739 	acpi_system_exit();
1740 
1741 	acpi_bus_remove(acpi_root, ACPI_BUS_REMOVAL_NORMAL);
1742 
1743 	status = AcpiTerminate();
1744 	if (ACPI_FAILURE(status))
1745 		DPRINT1("Unable to terminate the ACPI Interpreter\n");
1746 	else
1747 		DPRINT1("Interpreter disabled\n");
1748 
1749 	return_VOID;
1750 }
1751 
1752 
1753 int
acpi_init(void)1754 acpi_init (void)
1755 {
1756 	int			result = 0;
1757 
1758 	DPRINT("acpi_init\n");
1759 
1760 	DPRINT("Subsystem revision %08x\n",ACPI_CA_VERSION);
1761 
1762 	KeInitializeSpinLock(&acpi_bus_event_lock);
1763 	KeInitializeEvent(&AcpiEventQueue, NotificationEvent, FALSE);
1764 	ExInitializeFastMutex(&acpi_bus_drivers_lock);
1765 
1766 	result = acpi_bus_init();
1767 
1768 	//if (!result) {
1769 		//pci_mmcfg_late_init();
1770 		//if (!(pm_flags & PM_APM))
1771 		//	pm_flags |= PM_ACPI;
1772 		//else {
1773 			//DPRINT1("APM is already active, exiting\n");
1774 			//disable_acpi();
1775 			//result = -ENODEV;
1776 		//}
1777 	//} else
1778 	//	disable_acpi();
1779 
1780 	/*
1781 	 * If the laptop falls into the DMI check table, the power state check
1782 	 * will be disabled in the course of device power transistion.
1783 	 */
1784 	//dmi_check_system(power_nocheck_dmi_table);
1785 
1786 	/*
1787 	 * Install drivers required for proper enumeration of the
1788 	 * ACPI namespace.
1789 	 */
1790 	acpi_system_init();	/* ACPI System */
1791 	acpi_power_init();	/* ACPI Bus Power Management */
1792 	acpi_button_init();
1793 	//acpi_ec_init();		/* ACPI Embedded Controller */
1794 #ifdef CONFIG_ACPI_PCI
1795 	if (!acpi_pci_disabled) {
1796 		acpi_pci_link_init();	/* ACPI PCI Interrupt Link */
1797 		acpi_pci_root_init();	/* ACPI PCI Root Bridge */
1798 	}
1799 #endif
1800 
1801 	//acpi_scan_init();
1802 	//acpi_ec_init();
1803 	//acpi_power_init();
1804 	//acpi_system_init();
1805 	//acpi_debug_init();
1806 	//acpi_sleep_proc_init();
1807 	//acpi_wakeup_device_init();
1808 
1809 	return result;
1810 }
1811 
1812 
1813 void
acpi_exit(void)1814 acpi_exit (void)
1815 {
1816 	DPRINT("acpi_exit\n");
1817 
1818 #ifdef CONFIG_PM
1819 	pm_active = 0;
1820 #endif
1821 
1822 	acpi_bus_exit();
1823 
1824 	return_VOID;
1825 }
1826 
1827