File: /usr/src/linux/drivers/acpi/os.c
1 /******************************************************************************
2 *
3 * Module Name: os.c - Linux OSL functions
4 * $Revision: 46 $
5 *
6 *****************************************************************************/
7
8 /*
9 * os.c - OS-dependent functions
10 *
11 * Copyright (C) 2000 Andrew Henroid
12 * Copyright (C) 2001 Andrew Grover
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2 of the License, or
17 * (at your option) any later version.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, write to the Free Software
26 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
27 */
28 /* Changes
29 *
30 * Christopher Liebman <liebman@sponsera.com> 2001-5-15
31 * - Fixed improper kernel_thread parameters
32 */
33
34 #include <linux/kernel.h>
35 #include <linux/slab.h>
36 #include <linux/mm.h>
37 #include <linux/pci.h>
38 #include <linux/interrupt.h>
39 #include <linux/kmod.h>
40 #include <linux/delay.h>
41 #include <asm/io.h>
42 #include <acpi.h>
43 #include "driver.h"
44
45 #ifdef CONFIG_ACPI_EFI
46 #include <asm/efi.h>
47 #endif
48
49 #ifdef _IA64
50 #include <asm/hw_irq.h>
51 #endif
52
53 #define _COMPONENT ACPI_OS_SERVICES
54 MODULE_NAME ("os")
55
56 typedef struct
57 {
58 OSD_EXECUTION_CALLBACK function;
59 void *context;
60 } ACPI_OS_DPC;
61
62
63 /*****************************************************************************
64 * Debugger Stuff
65 *****************************************************************************/
66
67 #ifdef ENABLE_DEBUGGER
68
69 #include <linux/kdb.h>
70
71 /* stuff for debugger support */
72 int acpi_in_debugger = 0;
73 extern NATIVE_CHAR line_buf[80];
74
75 #endif
76
77
78 /*****************************************************************************
79 * Globals
80 *****************************************************************************/
81
82 static int acpi_irq_irq = 0;
83 static OSD_HANDLER acpi_irq_handler = NULL;
84 static void *acpi_irq_context = NULL;
85
86
87 /******************************************************************************
88 * Functions
89 *****************************************************************************/
90
91 acpi_status
92 acpi_os_initialize(void)
93 {
94 return AE_OK;
95 }
96
97 acpi_status
98 acpi_os_terminate(void)
99 {
100 if (acpi_irq_handler) {
101 acpi_os_remove_interrupt_handler(acpi_irq_irq,
102 acpi_irq_handler);
103 }
104
105 return AE_OK;
106 }
107
108 s32
109 acpi_os_printf(const NATIVE_CHAR *fmt,...)
110 {
111 s32 size;
112 va_list args;
113 va_start(args, fmt);
114 size = acpi_os_vprintf(fmt, args);
115 va_end(args);
116
117 return size;
118 }
119
120 s32
121 acpi_os_vprintf(const NATIVE_CHAR *fmt, va_list args)
122 {
123 static char buffer[512];
124 int size = vsprintf(buffer, fmt, args);
125
126 #ifdef ENABLE_DEBUGGER
127 if (acpi_in_debugger) {
128 kdb_printf("%s", buffer);
129 } else {
130 printk("%s", buffer);
131 }
132 #else
133 printk("%s", buffer);
134 #endif
135
136 return size;
137 }
138
139 void *
140 acpi_os_allocate(u32 size)
141 {
142 return kmalloc(size, GFP_KERNEL);
143 }
144
145 void *
146 acpi_os_callocate(u32 size)
147 {
148 void *ptr = acpi_os_allocate(size);
149 if (ptr)
150 memset(ptr, 0, size);
151
152 return ptr;
153 }
154
155 void
156 acpi_os_free(void *ptr)
157 {
158 kfree(ptr);
159 }
160
161
162 acpi_status
163 acpi_os_get_root_pointer(u32 flags, ACPI_PHYSICAL_ADDRESS *phys_addr)
164 {
165 #ifndef CONFIG_ACPI_EFI
166 if (ACPI_FAILURE(acpi_find_root_pointer(flags, phys_addr))) {
167 printk(KERN_ERR "ACPI: System description tables not found\n");
168 return AE_ERROR;
169 }
170 #else /*CONFIG_ACPI_EFI*/
171 if (efi.acpi20)
172 *phys_addr = (ACPI_PHYSICAL_ADDRESS) efi.acpi20;
173 else if (efi.acpi)
174 *phys_addr = (ACPI_PHYSICAL_ADDRESS) efi.acpi;
175 else {
176 printk(KERN_ERR "ACPI: System description tables not found\n");
177 *phys_addr = NULL;
178 return AE_ERROR;
179 }
180 #endif /*CONFIG_ACPI_EFI*/
181
182 return AE_OK;
183 }
184
185 acpi_status
186 acpi_os_map_memory(ACPI_PHYSICAL_ADDRESS phys, u32 size, void **virt)
187 {
188 if (phys > ULONG_MAX) {
189 printk(KERN_ERR "ACPI: Cannot map memory that high\n");
190 return AE_ERROR;
191 }
192
193 if ((unsigned long) phys < virt_to_phys(high_memory)) {
194 struct page *page;
195 *virt = phys_to_virt((unsigned long) phys);
196
197 /* Check for stamping */
198 page = virt_to_page(*virt);
199 if(page && !test_bit(PG_reserved, &page->flags))
200 printk(KERN_WARNING "ACPI attempting to access kernel owned memory at %08lX.\n", (unsigned long)phys);
201
202 return AE_OK;
203 }
204
205 *virt = ioremap((unsigned long) phys, size);
206 if (!*virt)
207 return AE_ERROR;
208
209 return AE_OK;
210 }
211
212 void
213 acpi_os_unmap_memory(void *virt, u32 size)
214 {
215 if (virt >= high_memory)
216 iounmap(virt);
217 }
218
219 acpi_status
220 acpi_os_get_physical_address(void *virt, ACPI_PHYSICAL_ADDRESS *phys)
221 {
222 if(!phys || !virt)
223 return AE_BAD_PARAMETER;
224
225 *phys = virt_to_phys(virt);
226
227 return AE_OK;
228 }
229
230 static void
231 acpi_irq(int irq, void *dev_id, struct pt_regs *regs)
232 {
233 (*acpi_irq_handler)(acpi_irq_context);
234 }
235
236 acpi_status
237 acpi_os_install_interrupt_handler(u32 irq, OSD_HANDLER handler, void *context)
238 {
239 #ifdef _IA64
240 irq = isa_irq_to_vector(irq);
241 #endif /*_IA64*/
242 acpi_irq_irq = irq;
243 acpi_irq_handler = handler;
244 acpi_irq_context = context;
245 if (request_irq(irq,
246 acpi_irq,
247 SA_SHIRQ,
248 "acpi",
249 acpi_irq)) {
250 printk(KERN_ERR "ACPI: SCI (IRQ%d) allocation failed\n", irq);
251 return AE_ERROR;
252 }
253
254 return AE_OK;
255 }
256
257 acpi_status
258 acpi_os_remove_interrupt_handler(u32 irq, OSD_HANDLER handler)
259 {
260 if (acpi_irq_handler) {
261 #ifdef _IA64
262 irq = isa_irq_to_vector(irq);
263 #endif /*_IA64*/
264 free_irq(irq, acpi_irq);
265 acpi_irq_handler = NULL;
266 }
267
268 return AE_OK;
269 }
270
271 /*
272 * Running in interpreter thread context, safe to sleep
273 */
274
275 void
276 acpi_os_sleep(u32 sec, u32 ms)
277 {
278 current->state = TASK_INTERRUPTIBLE;
279 schedule_timeout(HZ * sec + (ms * HZ) / 1000);
280 }
281
282 void
283 acpi_os_stall(u32 us)
284 {
285 if (us > 10000) {
286 mdelay(us / 1000);
287 }
288 else {
289 udelay(us);
290 }
291 }
292
293 acpi_status
294 acpi_os_read_port(
295 ACPI_IO_ADDRESS port,
296 void *value,
297 u32 width)
298 {
299 u32 dummy;
300
301 if (!value)
302 value = &dummy;
303
304 switch (width)
305 {
306 case 8:
307 *(u8*) value = inb(port);
308 break;
309 case 16:
310 *(u16*) value = inw(port);
311 break;
312 case 32:
313 *(u32*) value = inl(port);
314 break;
315 default:
316 BUG();
317 }
318
319 return AE_OK;
320 }
321
322 acpi_status
323 acpi_os_write_port(
324 ACPI_IO_ADDRESS port,
325 u32 value,
326 u32 width)
327 {
328 switch (width)
329 {
330 case 8:
331 outb(value, port);
332 break;
333 case 16:
334 outw(value, port);
335 break;
336 case 32:
337 outl(value, port);
338 break;
339 default:
340 BUG();
341 }
342
343 return AE_OK;
344 }
345
346 acpi_status
347 acpi_os_read_memory(
348 ACPI_PHYSICAL_ADDRESS phys_addr,
349 void *value,
350 u32 width)
351 {
352 u32 dummy;
353
354 if (!value)
355 value = &dummy;
356
357 switch (width)
358 {
359 case 8:
360 *(u8*) value = *(u8*) phys_to_virt(phys_addr);
361 break;
362 case 16:
363 *(u16*) value = *(u16*) phys_to_virt(phys_addr);
364 break;
365 case 32:
366 *(u32*) value = *(u32*) phys_to_virt(phys_addr);
367 break;
368 default:
369 BUG();
370 }
371
372 return AE_OK;
373 }
374
375 acpi_status
376 acpi_os_write_memory(
377 ACPI_PHYSICAL_ADDRESS phys_addr,
378 u32 value,
379 u32 width)
380 {
381 switch (width)
382 {
383 case 8:
384 *(u8*) phys_to_virt(phys_addr) = value;
385 break;
386 case 16:
387 *(u16*) phys_to_virt(phys_addr) = value;
388 break;
389 case 32:
390 *(u32*) phys_to_virt(phys_addr) = value;
391 break;
392 default:
393 BUG();
394 }
395
396 return AE_OK;
397 }
398
399
400 #ifdef CONFIG_ACPI_PCI
401
402 /* Architecture-dependent low-level PCI configuration access functions. */
403 extern int (*pci_config_read)(int seg, int bus, int dev, int fn, int reg, int len, u32 *val);
404 extern int (*pci_config_write)(int seg, int bus, int dev, int fn, int reg, int len, u32 val);
405
406 acpi_status
407 acpi_os_read_pci_configuration (
408 acpi_pci_id *pci_id,
409 u32 reg,
410 void *value,
411 u32 width)
412 {
413 int result = 0;
414 if (!value)
415 return AE_ERROR;
416
417 switch (width)
418 {
419 case 8:
420 result = pci_config_read(pci_id->segment, pci_id->bus,
421 pci_id->device, pci_id->function, reg, 1, value);
422 break;
423 case 16:
424 result = pci_config_read(pci_id->segment, pci_id->bus,
425 pci_id->device, pci_id->function, reg, 2, value);
426 break;
427 case 32:
428 result = pci_config_read(pci_id->segment, pci_id->bus,
429 pci_id->device, pci_id->function, reg, 4, value);
430 break;
431 default:
432 BUG();
433 }
434
435 return (result ? AE_ERROR : AE_OK);
436 }
437
438 acpi_status
439 acpi_os_write_pci_configuration (
440 acpi_pci_id *pci_id,
441 u32 reg,
442 NATIVE_UINT value,
443 u32 width)
444 {
445 int result = 0;
446
447 switch (width)
448 {
449 case 8:
450 result = pci_config_write(pci_id->segment, pci_id->bus,
451 pci_id->device, pci_id->function, reg, 1, value);
452 break;
453 case 16:
454 result = pci_config_write(pci_id->segment, pci_id->bus,
455 pci_id->device, pci_id->function, reg, 2, value);
456 break;
457 case 32:
458 result = pci_config_write(pci_id->segment, pci_id->bus,
459 pci_id->device, pci_id->function, reg, 4, value);
460 break;
461 default:
462 BUG();
463 }
464
465 return (result ? AE_ERROR : AE_OK);
466 }
467
468 #else /*CONFIG_ACPI_PCI*/
469
470 acpi_status
471 acpi_os_read_pci_configuration (
472 acpi_pci_id *pci_id,
473 u32 reg,
474 void *value,
475 u32 width)
476 {
477 int devfn = PCI_DEVFN(pci_id->device, pci_id->function);
478 struct pci_dev *dev = pci_find_slot(pci_id->bus, devfn);
479
480 if (!value || !dev)
481 return AE_ERROR;
482
483 switch (width)
484 {
485 case 8:
486 if (pci_read_config_byte(dev, reg, (u8*) value))
487 return AE_ERROR;
488 break;
489 case 16:
490 if (pci_read_config_word(dev, reg, (u16*) value))
491 return AE_ERROR;
492 break;
493 case 32:
494 if (pci_read_config_dword(dev, reg, (u32*) value))
495 return AE_ERROR;
496 break;
497 default:
498 BUG();
499 }
500
501 return AE_OK;
502 }
503
504 acpi_status
505 acpi_os_write_pci_configuration (
506 acpi_pci_id *pci_id,
507 u32 reg,
508 u32 value,
509 u32 width)
510 {
511 int devfn = PCI_DEVFN(pci_id->device, pci_id->function);
512 struct pci_dev *dev = pci_find_slot(pci_id->bus, devfn);
513
514 if (!dev)
515 return AE_ERROR;
516
517 switch (width)
518 {
519 case 8:
520 if (pci_write_config_byte(dev, reg, value))
521 return AE_ERROR;
522 break;
523 case 16:
524 if (pci_write_config_word(dev, reg, value))
525 return AE_ERROR;
526 break;
527 case 32:
528 if (pci_write_config_dword(dev, reg, value))
529 return AE_ERROR;
530 break;
531 default:
532 BUG();
533 }
534
535 return AE_OK;
536 }
537
538 #endif /*CONFIG_ACPI_PCI*/
539
540
541 acpi_status
542 acpi_os_load_module (
543 char *module_name)
544 {
545 PROC_NAME("acpi_os_load_module");
546
547 if (!module_name)
548 return AE_BAD_PARAMETER;
549
550 if (0 > request_module(module_name)) {
551 ACPI_DEBUG_PRINT ((ACPI_DB_WARN, "Unable to load module [%s].\n", module_name));
552 return AE_ERROR;
553 }
554
555 return AE_OK;
556 }
557
558 acpi_status
559 acpi_os_unload_module (
560 char *module_name)
561 {
562 if (!module_name)
563 return AE_BAD_PARAMETER;
564
565 /* TODO: How on Linux? */
566 /* this is done automatically for all modules with
567 use_count = 0, I think. see: MOD_INC_USE_COUNT -ASG */
568
569 return AE_OK;
570 }
571
572
573 /*
574 * See acpi_os_queue_for_execution()
575 */
576 static int
577 acpi_os_queue_exec (
578 void *context)
579 {
580 ACPI_OS_DPC *dpc = (ACPI_OS_DPC*)context;
581
582 PROC_NAME("acpi_os_queue_exec");
583
584 daemonize();
585 strcpy(current->comm, "kacpidpc");
586
587 if (!dpc || !dpc->function)
588 return AE_BAD_PARAMETER;
589
590 ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Executing function [%p(%p)].\n", dpc->function, dpc->context));
591
592 dpc->function(dpc->context);
593
594 kfree(dpc);
595
596 return 1;
597 }
598
599 static void
600 acpi_os_schedule_exec (
601 void *context)
602 {
603 ACPI_OS_DPC *dpc = NULL;
604 int thread_pid = -1;
605
606 PROC_NAME("acpi_os_schedule_exec");
607
608 dpc = (ACPI_OS_DPC*)context;
609 if (!dpc) {
610 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Invalid (NULL) context.\n"));
611 return;
612 }
613
614 ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Creating new thread to run function [%p(%p)].\n", dpc->function, dpc->context));
615
616 thread_pid = kernel_thread(acpi_os_queue_exec, dpc,
617 (CLONE_FS | CLONE_FILES | SIGCHLD));
618 if (thread_pid < 0) {
619 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Call to kernel_thread() failed.\n"));
620 acpi_os_free(dpc);
621 }
622 }
623
624 acpi_status
625 acpi_os_queue_for_execution(
626 u32 priority,
627 OSD_EXECUTION_CALLBACK function,
628 void *context)
629 {
630 acpi_status status = AE_OK;
631 ACPI_OS_DPC *dpc = NULL;
632
633 PROC_NAME("acpi_os_queue_for_execution");
634
635 ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Scheduling function [%p(%p)] for deferred execution.\n", function, context));
636
637 if (!function)
638 return AE_BAD_PARAMETER;
639
640 /*
641 * Queue via DPC:
642 * --------------
643 * Note that we have to use two different processes for queuing DPCs:
644 * Interrupt-Level: Use schedule_task; can't spawn a new thread.
645 * Kernel-Level: Spawn a new kernel thread, as schedule_task has
646 * its limitations (e.g. single-threaded model), and
647 * all other task queues run at interrupt-level.
648 */
649 switch (priority) {
650
651 case OSD_PRIORITY_GPE:
652 {
653 static struct tq_struct task;
654
655 /*
656 * Allocate/initialize DPC structure. Note that this memory will be
657 * freed by the callee.
658 */
659 dpc = kmalloc(sizeof(ACPI_OS_DPC), GFP_ATOMIC);
660 if (!dpc)
661 return AE_NO_MEMORY;
662
663 dpc->function = function;
664 dpc->context = context;
665
666 memset(&task, 0, sizeof(struct tq_struct));
667
668 task.routine = acpi_os_schedule_exec;
669 task.data = (void*)dpc;
670
671 if (schedule_task(&task) < 0) {
672 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Call to schedule_task() failed.\n"));
673 status = AE_ERROR;
674 }
675 }
676 break;
677
678 default:
679 /*
680 * Allocate/initialize DPC structure. Note that this memory will be
681 * freed by the callee.
682 */
683 dpc = kmalloc(sizeof(ACPI_OS_DPC), GFP_KERNEL);
684 if (!dpc)
685 return AE_NO_MEMORY;
686
687 dpc->function = function;
688 dpc->context = context;
689
690 acpi_os_schedule_exec(dpc);
691 break;
692 }
693
694 return status;
695 }
696
697
698 acpi_status
699 acpi_os_create_semaphore(
700 u32 max_units,
701 u32 initial_units,
702 acpi_handle *handle)
703 {
704 struct semaphore *sem = NULL;
705
706 PROC_NAME("acpi_os_create_semaphore");
707
708 sem = acpi_os_callocate(sizeof(struct semaphore));
709 if (!sem)
710 return AE_NO_MEMORY;
711
712 sema_init(sem, initial_units);
713
714 *handle = (acpi_handle*)sem;
715
716 ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Creating semaphore[%p|%d].\n", *handle, initial_units));
717
718 return AE_OK;
719 }
720
721
722 /*
723 * TODO: A better way to delete semaphores? Linux doesn't have a
724 * 'delete_semaphore()' function -- may result in an invalid
725 * pointer dereference for non-synchronized consumers. Should
726 * we at least check for blocked threads and signal/cancel them?
727 */
728
729 acpi_status
730 acpi_os_delete_semaphore(
731 acpi_handle handle)
732 {
733 struct semaphore *sem = (struct semaphore*) handle;
734
735 PROC_NAME("acpi_os_delete_semaphore");
736
737 if (!sem)
738 return AE_BAD_PARAMETER;
739
740 ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Deleting semaphore[%p].\n", handle));
741
742 acpi_os_free(sem); sem = NULL;
743
744 return AE_OK;
745 }
746
747
748 /*
749 * TODO: The kernel doesn't have a 'down_timeout' function -- had to
750 * improvise. The process is to sleep for one scheduler quantum
751 * until the semaphore becomes available. Downside is that this
752 * may result in starvation for timeout-based waits when there's
753 * lots of semaphore activity.
754 *
755 * TODO: Support for units > 1?
756 */
757 acpi_status
758 acpi_os_wait_semaphore(
759 acpi_handle handle,
760 u32 units,
761 u32 timeout)
762 {
763 acpi_status status = AE_OK;
764 struct semaphore *sem = (struct semaphore*)handle;
765 int ret = 0;
766
767 PROC_NAME("acpi_os_wait_semaphore");
768
769 if (!sem || (units < 1))
770 return AE_BAD_PARAMETER;
771
772 if (units > 1)
773 return AE_SUPPORT;
774
775 ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Waiting for semaphore[%p|%d|%d]\n", handle, units, timeout));
776
777 switch (timeout)
778 {
779 /*
780 * No Wait:
781 * --------
782 * A zero timeout value indicates that we shouldn't wait - just
783 * acquire the semaphore if available otherwise return AE_TIME
784 * (a.k.a. 'would block').
785 */
786 case 0:
787 if(down_trylock(sem))
788 status = AE_TIME;
789 break;
790
791 /*
792 * Wait Indefinitely:
793 * ------------------
794 */
795 case WAIT_FOREVER:
796 ret = down_interruptible(sem);
797 if (ret < 0)
798 status = AE_ERROR;
799 break;
800
801 /*
802 * Wait w/ Timeout:
803 * ----------------
804 */
805 default:
806 // TODO: A better timeout algorithm?
807 {
808 int i = 0;
809 static const int quantum_ms = 1000/HZ;
810
811 ret = down_trylock(sem);
812 for (i = timeout; (i > 0 && ret < 0); i -= quantum_ms) {
813 current->state = TASK_INTERRUPTIBLE;
814 schedule_timeout(1);
815 ret = down_trylock(sem);
816 }
817
818 if (ret != 0)
819 status = AE_TIME;
820 }
821 break;
822 }
823
824 if (ACPI_FAILURE(status)) {
825 ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Failed to acquire semaphore[%p|%d|%d]\n", handle, units, timeout));
826 }
827 else {
828 ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Acquired semaphore[%p|%d|%d]\n", handle, units, timeout));
829 }
830
831 return status;
832 }
833
834
835 /*
836 * TODO: Support for units > 1?
837 */
838 acpi_status
839 acpi_os_signal_semaphore(
840 acpi_handle handle,
841 u32 units)
842 {
843 struct semaphore *sem = (struct semaphore *) handle;
844
845 PROC_NAME("acpi_os_signal_semaphore");
846
847 if (!sem || (units < 1))
848 return AE_BAD_PARAMETER;
849
850 if (units > 1)
851 return AE_SUPPORT;
852
853 ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Signaling semaphore[%p|%d]\n", handle, units));
854
855 up(sem);
856
857 return AE_OK;
858 }
859
860 u32
861 acpi_os_get_line(NATIVE_CHAR *buffer)
862 {
863
864 #ifdef ENABLE_DEBUGGER
865 if (acpi_in_debugger) {
866 u32 chars;
867
868 kdb_read(buffer, sizeof(line_buf));
869
870 /* remove the CR kdb includes */
871 chars = strlen(buffer) - 1;
872 buffer[chars] = '\0';
873 }
874 #endif
875
876 return 0;
877 }
878
879 /*
880 * We just have to assume we're dealing with valid memory
881 */
882
883 BOOLEAN
884 acpi_os_readable(void *ptr, u32 len)
885 {
886 return 1;
887 }
888
889 BOOLEAN
890 acpi_os_writable(void *ptr, u32 len)
891 {
892 return 1;
893 }
894
895 u32
896 acpi_os_get_thread_id (void)
897 {
898 if (!in_interrupt())
899 return current->pid;
900
901 return 0;
902 }
903
904 acpi_status
905 acpi_os_signal (
906 u32 function,
907 void *info)
908 {
909 switch (function)
910 {
911 case ACPI_SIGNAL_FATAL:
912 printk(KERN_ERR "ACPI: Fatal opcode executed\n");
913 break;
914 case ACPI_SIGNAL_BREAKPOINT:
915 {
916 char *bp_info = (char*) info;
917
918 printk(KERN_ERR "ACPI breakpoint: %s\n", bp_info);
919 }
920 default:
921 break;
922 }
923
924 return AE_OK;
925 }
926
927 acpi_status
928 acpi_os_breakpoint(NATIVE_CHAR *msg)
929 {
930 acpi_os_printf("breakpoint: %s", msg);
931
932 return AE_OK;
933 }
934
935