1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30#include <linux/module.h>
31#include <linux/kernel.h>
32#include <linux/slab.h>
33#include <linux/mm.h>
34#include <linux/pci.h>
35#include <linux/interrupt.h>
36#include <linux/kmod.h>
37#include <linux/delay.h>
38#include <linux/workqueue.h>
39#include <linux/nmi.h>
40#include <linux/acpi.h>
41#include <linux/efi.h>
42#include <linux/ioport.h>
43#include <linux/list.h>
44#include <linux/jiffies.h>
45#include <linux/semaphore.h>
46
47#include <asm/io.h>
48#include <asm/uaccess.h>
49
50#include <acpi/acpi.h>
51#include <acpi/acpi_bus.h>
52#include <acpi/processor.h>
53
54#define _COMPONENT ACPI_OS_SERVICES
55ACPI_MODULE_NAME("osl");
56#define PREFIX "ACPI: "
57struct acpi_os_dpc {
58 acpi_osd_exec_callback function;
59 void *context;
60 struct work_struct work;
61 int wait;
62};
63
64#ifdef CONFIG_ACPI_CUSTOM_DSDT
65#include CONFIG_ACPI_CUSTOM_DSDT_FILE
66#endif
67
68#ifdef ENABLE_DEBUGGER
69#include <linux/kdb.h>
70
71
72int acpi_in_debugger;
73EXPORT_SYMBOL(acpi_in_debugger);
74
75extern char line_buf[80];
76#endif
77
78static unsigned int acpi_irq_irq;
79static acpi_osd_handler acpi_irq_handler;
80static void *acpi_irq_context;
81static struct workqueue_struct *kacpid_wq;
82static struct workqueue_struct *kacpi_notify_wq;
83static struct workqueue_struct *kacpi_hotplug_wq;
84
85struct acpi_res_list {
86 resource_size_t start;
87 resource_size_t end;
88 acpi_adr_space_type resource_type;
89 char name[5];
90
91 struct list_head resource_list;
92 int count;
93};
94
95static LIST_HEAD(resource_list_head);
96static DEFINE_SPINLOCK(acpi_res_lock);
97
98#define OSI_STRING_LENGTH_MAX 64
99static char osi_additional_string[OSI_STRING_LENGTH_MAX];
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134static struct osi_linux {
135 unsigned int enable:1;
136 unsigned int dmi:1;
137 unsigned int cmdline:1;
138 unsigned int known:1;
139} osi_linux = { 0, 0, 0, 0};
140
141static void __init acpi_request_region (struct acpi_generic_address *addr,
142 unsigned int length, char *desc)
143{
144 struct resource *res;
145
146 if (!addr->address || !length)
147 return;
148
149 if (addr->space_id == ACPI_ADR_SPACE_SYSTEM_IO)
150 res = request_region(addr->address, length, desc);
151 else if (addr->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY)
152 res = request_mem_region(addr->address, length, desc);
153}
154
155static int __init acpi_reserve_resources(void)
156{
157 acpi_request_region(&acpi_gbl_FADT.xpm1a_event_block, acpi_gbl_FADT.pm1_event_length,
158 "ACPI PM1a_EVT_BLK");
159
160 acpi_request_region(&acpi_gbl_FADT.xpm1b_event_block, acpi_gbl_FADT.pm1_event_length,
161 "ACPI PM1b_EVT_BLK");
162
163 acpi_request_region(&acpi_gbl_FADT.xpm1a_control_block, acpi_gbl_FADT.pm1_control_length,
164 "ACPI PM1a_CNT_BLK");
165
166 acpi_request_region(&acpi_gbl_FADT.xpm1b_control_block, acpi_gbl_FADT.pm1_control_length,
167 "ACPI PM1b_CNT_BLK");
168
169 if (acpi_gbl_FADT.pm_timer_length == 4)
170 acpi_request_region(&acpi_gbl_FADT.xpm_timer_block, 4, "ACPI PM_TMR");
171
172 acpi_request_region(&acpi_gbl_FADT.xpm2_control_block, acpi_gbl_FADT.pm2_control_length,
173 "ACPI PM2_CNT_BLK");
174
175
176
177 if (!(acpi_gbl_FADT.gpe0_block_length & 0x1))
178 acpi_request_region(&acpi_gbl_FADT.xgpe0_block,
179 acpi_gbl_FADT.gpe0_block_length, "ACPI GPE0_BLK");
180
181 if (!(acpi_gbl_FADT.gpe1_block_length & 0x1))
182 acpi_request_region(&acpi_gbl_FADT.xgpe1_block,
183 acpi_gbl_FADT.gpe1_block_length, "ACPI GPE1_BLK");
184
185 return 0;
186}
187device_initcall(acpi_reserve_resources);
188
189acpi_status __init acpi_os_initialize(void)
190{
191 return AE_OK;
192}
193
194static void bind_to_cpu0(struct work_struct *work)
195{
196 set_cpus_allowed_ptr(current, cpumask_of(0));
197 kfree(work);
198}
199
200static void bind_workqueue(struct workqueue_struct *wq)
201{
202 struct work_struct *work;
203
204 work = kzalloc(sizeof(struct work_struct), GFP_KERNEL);
205 INIT_WORK(work, bind_to_cpu0);
206 queue_work(wq, work);
207}
208
209acpi_status acpi_os_initialize1(void)
210{
211
212
213
214
215
216
217
218 kacpid_wq = create_singlethread_workqueue("kacpid");
219 bind_workqueue(kacpid_wq);
220 kacpi_notify_wq = create_singlethread_workqueue("kacpi_notify");
221 bind_workqueue(kacpi_notify_wq);
222 kacpi_hotplug_wq = create_singlethread_workqueue("kacpi_hotplug");
223 bind_workqueue(kacpi_hotplug_wq);
224 BUG_ON(!kacpid_wq);
225 BUG_ON(!kacpi_notify_wq);
226 BUG_ON(!kacpi_hotplug_wq);
227 return AE_OK;
228}
229
230acpi_status acpi_os_terminate(void)
231{
232 if (acpi_irq_handler) {
233 acpi_os_remove_interrupt_handler(acpi_irq_irq,
234 acpi_irq_handler);
235 }
236
237 destroy_workqueue(kacpid_wq);
238 destroy_workqueue(kacpi_notify_wq);
239 destroy_workqueue(kacpi_hotplug_wq);
240
241 return AE_OK;
242}
243
244void acpi_os_printf(const char *fmt, ...)
245{
246 va_list args;
247 va_start(args, fmt);
248 acpi_os_vprintf(fmt, args);
249 va_end(args);
250}
251
252void acpi_os_vprintf(const char *fmt, va_list args)
253{
254 static char buffer[512];
255
256 vsprintf(buffer, fmt, args);
257
258#ifdef ENABLE_DEBUGGER
259 if (acpi_in_debugger) {
260 kdb_printf("%s", buffer);
261 } else {
262 printk(KERN_CONT "%s", buffer);
263 }
264#else
265 printk(KERN_CONT "%s", buffer);
266#endif
267}
268
269acpi_physical_address __init acpi_os_get_root_pointer(void)
270{
271 if (efi_enabled) {
272 if (efi.acpi20 != EFI_INVALID_TABLE_ADDR)
273 return efi.acpi20;
274 else if (efi.acpi != EFI_INVALID_TABLE_ADDR)
275 return efi.acpi;
276 else {
277 printk(KERN_ERR PREFIX
278 "System description tables not found\n");
279 return 0;
280 }
281 } else {
282 acpi_physical_address pa = 0;
283
284 acpi_find_root_pointer(&pa);
285 return pa;
286 }
287}
288
289void __iomem *__init_refok
290acpi_os_map_memory(acpi_physical_address phys, acpi_size size)
291{
292 if (phys > ULONG_MAX) {
293 printk(KERN_ERR PREFIX "Cannot map memory that high\n");
294 return NULL;
295 }
296 if (acpi_gbl_permanent_mmap)
297
298
299
300 return ioremap((unsigned long)phys, size);
301 else
302 return __acpi_map_table((unsigned long)phys, size);
303}
304EXPORT_SYMBOL_GPL(acpi_os_map_memory);
305
306void __ref acpi_os_unmap_memory(void __iomem *virt, acpi_size size)
307{
308 if (acpi_gbl_permanent_mmap)
309 iounmap(virt);
310 else
311 __acpi_unmap_table(virt, size);
312}
313EXPORT_SYMBOL_GPL(acpi_os_unmap_memory);
314
315void __init early_acpi_os_unmap_memory(void __iomem *virt, acpi_size size)
316{
317 if (!acpi_gbl_permanent_mmap)
318 __acpi_unmap_table(virt, size);
319}
320
321#ifdef ACPI_FUTURE_USAGE
322acpi_status
323acpi_os_get_physical_address(void *virt, acpi_physical_address * phys)
324{
325 if (!phys || !virt)
326 return AE_BAD_PARAMETER;
327
328 *phys = virt_to_phys(virt);
329
330 return AE_OK;
331}
332#endif
333
334#define ACPI_MAX_OVERRIDE_LEN 100
335
336static char acpi_os_name[ACPI_MAX_OVERRIDE_LEN];
337
338acpi_status
339acpi_os_predefined_override(const struct acpi_predefined_names *init_val,
340 acpi_string * new_val)
341{
342 if (!init_val || !new_val)
343 return AE_BAD_PARAMETER;
344
345 *new_val = NULL;
346 if (!memcmp(init_val->name, "_OS_", 4) && strlen(acpi_os_name)) {
347 printk(KERN_INFO PREFIX "Overriding _OS definition to '%s'\n",
348 acpi_os_name);
349 *new_val = acpi_os_name;
350 }
351
352 return AE_OK;
353}
354
355acpi_status
356acpi_os_table_override(struct acpi_table_header * existing_table,
357 struct acpi_table_header ** new_table)
358{
359 if (!existing_table || !new_table)
360 return AE_BAD_PARAMETER;
361
362 *new_table = NULL;
363
364#ifdef CONFIG_ACPI_CUSTOM_DSDT
365 if (strncmp(existing_table->signature, "DSDT", 4) == 0)
366 *new_table = (struct acpi_table_header *)AmlCode;
367#endif
368 if (*new_table != NULL) {
369 printk(KERN_WARNING PREFIX "Override [%4.4s-%8.8s], "
370 "this is unsafe: tainting kernel\n",
371 existing_table->signature,
372 existing_table->oem_table_id);
373 add_taint(TAINT_OVERRIDDEN_ACPI_TABLE);
374 }
375 return AE_OK;
376}
377
378static irqreturn_t acpi_irq(int irq, void *dev_id)
379{
380 u32 handled;
381
382 handled = (*acpi_irq_handler) (acpi_irq_context);
383
384 if (handled) {
385 acpi_irq_handled++;
386 return IRQ_HANDLED;
387 } else {
388 acpi_irq_not_handled++;
389 return IRQ_NONE;
390 }
391}
392
393acpi_status
394acpi_os_install_interrupt_handler(u32 gsi, acpi_osd_handler handler,
395 void *context)
396{
397 unsigned int irq;
398
399 acpi_irq_stats_init();
400
401
402
403
404
405
406 gsi = acpi_gbl_FADT.sci_interrupt;
407 if (acpi_gsi_to_irq(gsi, &irq) < 0) {
408 printk(KERN_ERR PREFIX "SCI (ACPI GSI %d) not registered\n",
409 gsi);
410 return AE_OK;
411 }
412
413 acpi_irq_handler = handler;
414 acpi_irq_context = context;
415 if (request_irq(irq, acpi_irq, IRQF_SHARED, "acpi", acpi_irq)) {
416 printk(KERN_ERR PREFIX "SCI (IRQ%d) allocation failed\n", irq);
417 return AE_NOT_ACQUIRED;
418 }
419 acpi_irq_irq = irq;
420
421 return AE_OK;
422}
423
424acpi_status acpi_os_remove_interrupt_handler(u32 irq, acpi_osd_handler handler)
425{
426 if (irq) {
427 free_irq(irq, acpi_irq);
428 acpi_irq_handler = NULL;
429 acpi_irq_irq = 0;
430 }
431
432 return AE_OK;
433}
434
435
436
437
438
439void acpi_os_sleep(acpi_integer ms)
440{
441 schedule_timeout_interruptible(msecs_to_jiffies(ms));
442}
443
444void acpi_os_stall(u32 us)
445{
446 while (us) {
447 u32 delay = 1000;
448
449 if (delay > us)
450 delay = us;
451 udelay(delay);
452 touch_nmi_watchdog();
453 us -= delay;
454 }
455}
456
457
458
459
460
461
462u64 acpi_os_get_timer(void)
463{
464 static u64 t;
465
466#ifdef CONFIG_HPET
467
468#endif
469
470#ifdef CONFIG_X86_PM_TIMER
471
472#endif
473 if (!t)
474 printk(KERN_ERR PREFIX "acpi_os_get_timer() TBD\n");
475
476 return ++t;
477}
478
479acpi_status acpi_os_read_port(acpi_io_address port, u32 * value, u32 width)
480{
481 u32 dummy;
482
483 if (!value)
484 value = &dummy;
485
486 *value = 0;
487 if (width <= 8) {
488 *(u8 *) value = inb(port);
489 } else if (width <= 16) {
490 *(u16 *) value = inw(port);
491 } else if (width <= 32) {
492 *(u32 *) value = inl(port);
493 } else {
494 BUG();
495 }
496
497 return AE_OK;
498}
499
500EXPORT_SYMBOL(acpi_os_read_port);
501
502acpi_status acpi_os_write_port(acpi_io_address port, u32 value, u32 width)
503{
504 if (width <= 8) {
505 outb(value, port);
506 } else if (width <= 16) {
507 outw(value, port);
508 } else if (width <= 32) {
509 outl(value, port);
510 } else {
511 BUG();
512 }
513
514 return AE_OK;
515}
516
517EXPORT_SYMBOL(acpi_os_write_port);
518
519acpi_status
520acpi_os_read_memory(acpi_physical_address phys_addr, u32 * value, u32 width)
521{
522 u32 dummy;
523 void __iomem *virt_addr;
524
525 virt_addr = ioremap(phys_addr, width);
526 if (!value)
527 value = &dummy;
528
529 switch (width) {
530 case 8:
531 *(u8 *) value = readb(virt_addr);
532 break;
533 case 16:
534 *(u16 *) value = readw(virt_addr);
535 break;
536 case 32:
537 *(u32 *) value = readl(virt_addr);
538 break;
539 default:
540 BUG();
541 }
542
543 iounmap(virt_addr);
544
545 return AE_OK;
546}
547
548acpi_status
549acpi_os_write_memory(acpi_physical_address phys_addr, u32 value, u32 width)
550{
551 void __iomem *virt_addr;
552
553 virt_addr = ioremap(phys_addr, width);
554
555 switch (width) {
556 case 8:
557 writeb(value, virt_addr);
558 break;
559 case 16:
560 writew(value, virt_addr);
561 break;
562 case 32:
563 writel(value, virt_addr);
564 break;
565 default:
566 BUG();
567 }
568
569 iounmap(virt_addr);
570
571 return AE_OK;
572}
573
574acpi_status
575acpi_os_read_pci_configuration(struct acpi_pci_id * pci_id, u32 reg,
576 u32 *value, u32 width)
577{
578 int result, size;
579
580 if (!value)
581 return AE_BAD_PARAMETER;
582
583 switch (width) {
584 case 8:
585 size = 1;
586 break;
587 case 16:
588 size = 2;
589 break;
590 case 32:
591 size = 4;
592 break;
593 default:
594 return AE_ERROR;
595 }
596
597 result = raw_pci_read(pci_id->segment, pci_id->bus,
598 PCI_DEVFN(pci_id->device, pci_id->function),
599 reg, size, value);
600
601 return (result ? AE_ERROR : AE_OK);
602}
603
604acpi_status
605acpi_os_write_pci_configuration(struct acpi_pci_id * pci_id, u32 reg,
606 acpi_integer value, u32 width)
607{
608 int result, size;
609
610 switch (width) {
611 case 8:
612 size = 1;
613 break;
614 case 16:
615 size = 2;
616 break;
617 case 32:
618 size = 4;
619 break;
620 default:
621 return AE_ERROR;
622 }
623
624 result = raw_pci_write(pci_id->segment, pci_id->bus,
625 PCI_DEVFN(pci_id->device, pci_id->function),
626 reg, size, value);
627
628 return (result ? AE_ERROR : AE_OK);
629}
630
631
632static void acpi_os_derive_pci_id_2(acpi_handle rhandle,
633 acpi_handle chandle,
634 struct acpi_pci_id **id,
635 int *is_bridge, u8 * bus_number)
636{
637 acpi_handle handle;
638 struct acpi_pci_id *pci_id = *id;
639 acpi_status status;
640 unsigned long long temp;
641 acpi_object_type type;
642
643 acpi_get_parent(chandle, &handle);
644 if (handle != rhandle) {
645 acpi_os_derive_pci_id_2(rhandle, handle, &pci_id, is_bridge,
646 bus_number);
647
648 status = acpi_get_type(handle, &type);
649 if ((ACPI_FAILURE(status)) || (type != ACPI_TYPE_DEVICE))
650 return;
651
652 status = acpi_evaluate_integer(handle, METHOD_NAME__ADR, NULL,
653 &temp);
654 if (ACPI_SUCCESS(status)) {
655 u32 val;
656 pci_id->device = ACPI_HIWORD(ACPI_LODWORD(temp));
657 pci_id->function = ACPI_LOWORD(ACPI_LODWORD(temp));
658
659 if (*is_bridge)
660 pci_id->bus = *bus_number;
661
662
663 status =
664 acpi_os_read_pci_configuration(pci_id, 0x0e, &val,
665 8);
666 if (ACPI_SUCCESS(status)
667 && ((val & 0x7f) == 1 || (val & 0x7f) == 2)) {
668 status =
669 acpi_os_read_pci_configuration(pci_id, 0x18,
670 &val, 8);
671 if (!ACPI_SUCCESS(status)) {
672
673 return;
674 }
675 *is_bridge = 1;
676 pci_id->bus = val;
677 status =
678 acpi_os_read_pci_configuration(pci_id, 0x19,
679 &val, 8);
680 if (ACPI_SUCCESS(status)) {
681 *bus_number = val;
682 }
683 } else
684 *is_bridge = 0;
685 }
686 }
687}
688
689void acpi_os_derive_pci_id(acpi_handle rhandle,
690 acpi_handle chandle,
691 struct acpi_pci_id **id)
692{
693 int is_bridge = 1;
694 u8 bus_number = (*id)->bus;
695
696 acpi_os_derive_pci_id_2(rhandle, chandle, id, &is_bridge, &bus_number);
697}
698
699static void acpi_os_execute_deferred(struct work_struct *work)
700{
701 struct acpi_os_dpc *dpc = container_of(work, struct acpi_os_dpc, work);
702
703 if (dpc->wait)
704 acpi_os_wait_events_complete(NULL);
705
706 dpc->function(dpc->context);
707 kfree(dpc);
708}
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725static acpi_status __acpi_os_execute(acpi_execute_type type,
726 acpi_osd_exec_callback function, void *context, int hp)
727{
728 acpi_status status = AE_OK;
729 struct acpi_os_dpc *dpc;
730 struct workqueue_struct *queue;
731 int ret;
732 ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
733 "Scheduling function [%p(%p)] for deferred execution.\n",
734 function, context));
735
736
737
738
739
740
741
742
743
744
745 dpc = kmalloc(sizeof(struct acpi_os_dpc), GFP_ATOMIC);
746 if (!dpc)
747 return AE_NO_MEMORY;
748
749 dpc->function = function;
750 dpc->context = context;
751
752
753
754
755
756
757
758 queue = hp ? kacpi_hotplug_wq :
759 (type == OSL_NOTIFY_HANDLER ? kacpi_notify_wq : kacpid_wq);
760 dpc->wait = hp ? 1 : 0;
761 INIT_WORK(&dpc->work, acpi_os_execute_deferred);
762 ret = queue_work(queue, &dpc->work);
763
764 if (!ret) {
765 printk(KERN_ERR PREFIX
766 "Call to queue_work() failed.\n");
767 status = AE_ERROR;
768 kfree(dpc);
769 }
770 return status;
771}
772
773acpi_status acpi_os_execute(acpi_execute_type type,
774 acpi_osd_exec_callback function, void *context)
775{
776 return __acpi_os_execute(type, function, context, 0);
777}
778EXPORT_SYMBOL(acpi_os_execute);
779
780acpi_status acpi_os_hotplug_execute(acpi_osd_exec_callback function,
781 void *context)
782{
783 return __acpi_os_execute(0, function, context, 1);
784}
785
786void acpi_os_wait_events_complete(void *context)
787{
788 flush_workqueue(kacpid_wq);
789 flush_workqueue(kacpi_notify_wq);
790}
791
792EXPORT_SYMBOL(acpi_os_wait_events_complete);
793
794
795
796
797acpi_status acpi_os_create_lock(acpi_spinlock * handle)
798{
799 spin_lock_init(*handle);
800
801 return AE_OK;
802}
803
804
805
806
807void acpi_os_delete_lock(acpi_spinlock handle)
808{
809 return;
810}
811
812acpi_status
813acpi_os_create_semaphore(u32 max_units, u32 initial_units, acpi_handle * handle)
814{
815 struct semaphore *sem = NULL;
816
817 sem = acpi_os_allocate(sizeof(struct semaphore));
818 if (!sem)
819 return AE_NO_MEMORY;
820 memset(sem, 0, sizeof(struct semaphore));
821
822 sema_init(sem, initial_units);
823
824 *handle = (acpi_handle *) sem;
825
826 ACPI_DEBUG_PRINT((ACPI_DB_MUTEX, "Creating semaphore[%p|%d].\n",
827 *handle, initial_units));
828
829 return AE_OK;
830}
831
832
833
834
835
836
837
838
839acpi_status acpi_os_delete_semaphore(acpi_handle handle)
840{
841 struct semaphore *sem = (struct semaphore *)handle;
842
843 if (!sem)
844 return AE_BAD_PARAMETER;
845
846 ACPI_DEBUG_PRINT((ACPI_DB_MUTEX, "Deleting semaphore[%p].\n", handle));
847
848 BUG_ON(!list_empty(&sem->wait_list));
849 kfree(sem);
850 sem = NULL;
851
852 return AE_OK;
853}
854
855
856
857
858acpi_status acpi_os_wait_semaphore(acpi_handle handle, u32 units, u16 timeout)
859{
860 acpi_status status = AE_OK;
861 struct semaphore *sem = (struct semaphore *)handle;
862 long jiffies;
863 int ret = 0;
864
865 if (!sem || (units < 1))
866 return AE_BAD_PARAMETER;
867
868 if (units > 1)
869 return AE_SUPPORT;
870
871 ACPI_DEBUG_PRINT((ACPI_DB_MUTEX, "Waiting for semaphore[%p|%d|%d]\n",
872 handle, units, timeout));
873
874 if (timeout == ACPI_WAIT_FOREVER)
875 jiffies = MAX_SCHEDULE_TIMEOUT;
876 else
877 jiffies = msecs_to_jiffies(timeout);
878
879 ret = down_timeout(sem, jiffies);
880 if (ret)
881 status = AE_TIME;
882
883 if (ACPI_FAILURE(status)) {
884 ACPI_DEBUG_PRINT((ACPI_DB_MUTEX,
885 "Failed to acquire semaphore[%p|%d|%d], %s",
886 handle, units, timeout,
887 acpi_format_exception(status)));
888 } else {
889 ACPI_DEBUG_PRINT((ACPI_DB_MUTEX,
890 "Acquired semaphore[%p|%d|%d]", handle,
891 units, timeout));
892 }
893
894 return status;
895}
896
897
898
899
900acpi_status acpi_os_signal_semaphore(acpi_handle handle, u32 units)
901{
902 struct semaphore *sem = (struct semaphore *)handle;
903
904 if (!sem || (units < 1))
905 return AE_BAD_PARAMETER;
906
907 if (units > 1)
908 return AE_SUPPORT;
909
910 ACPI_DEBUG_PRINT((ACPI_DB_MUTEX, "Signaling semaphore[%p|%d]\n", handle,
911 units));
912
913 up(sem);
914
915 return AE_OK;
916}
917
918#ifdef ACPI_FUTURE_USAGE
919u32 acpi_os_get_line(char *buffer)
920{
921
922#ifdef ENABLE_DEBUGGER
923 if (acpi_in_debugger) {
924 u32 chars;
925
926 kdb_read(buffer, sizeof(line_buf));
927
928
929 chars = strlen(buffer) - 1;
930 buffer[chars] = '\0';
931 }
932#endif
933
934 return 0;
935}
936#endif
937
938acpi_status acpi_os_signal(u32 function, void *info)
939{
940 switch (function) {
941 case ACPI_SIGNAL_FATAL:
942 printk(KERN_ERR PREFIX "Fatal opcode executed\n");
943 break;
944 case ACPI_SIGNAL_BREAKPOINT:
945
946
947
948
949
950
951
952
953 break;
954 default:
955 break;
956 }
957
958 return AE_OK;
959}
960
961static int __init acpi_os_name_setup(char *str)
962{
963 char *p = acpi_os_name;
964 int count = ACPI_MAX_OVERRIDE_LEN - 1;
965
966 if (!str || !*str)
967 return 0;
968
969 for (; count-- && str && *str; str++) {
970 if (isalnum(*str) || *str == ' ' || *str == ':')
971 *p++ = *str;
972 else if (*str == '\'' || *str == '"')
973 continue;
974 else
975 break;
976 }
977 *p = 0;
978
979 return 1;
980
981}
982
983__setup("acpi_os_name=", acpi_os_name_setup);
984
985static void __init set_osi_linux(unsigned int enable)
986{
987 if (osi_linux.enable != enable) {
988 osi_linux.enable = enable;
989 printk(KERN_NOTICE PREFIX "%sed _OSI(Linux)\n",
990 enable ? "Add": "Delet");
991 }
992 return;
993}
994
995static void __init acpi_cmdline_osi_linux(unsigned int enable)
996{
997 osi_linux.cmdline = 1;
998 set_osi_linux(enable);
999
1000 return;
1001}
1002
1003void __init acpi_dmi_osi_linux(int enable, const struct dmi_system_id *d)
1004{
1005 osi_linux.dmi = 1;
1006
1007 printk(KERN_NOTICE PREFIX "DMI detected: %s\n", d->ident);
1008
1009 if (enable == -1)
1010 return;
1011
1012 osi_linux.known = 1;
1013
1014 set_osi_linux(enable);
1015
1016 return;
1017}
1018
1019
1020
1021
1022
1023
1024
1025
1026int __init acpi_osi_setup(char *str)
1027{
1028 if (str == NULL || *str == '\0') {
1029 printk(KERN_INFO PREFIX "_OSI method disabled\n");
1030 acpi_gbl_create_osi_method = FALSE;
1031 } else if (!strcmp("!Linux", str)) {
1032 acpi_cmdline_osi_linux(0);
1033 } else if (*str == '!') {
1034 if (acpi_osi_invalidate(++str) == AE_OK)
1035 printk(KERN_INFO PREFIX "Deleted _OSI(%s)\n", str);
1036 } else if (!strcmp("Linux", str)) {
1037 acpi_cmdline_osi_linux(1);
1038 } else if (*osi_additional_string == '\0') {
1039 strncpy(osi_additional_string, str, OSI_STRING_LENGTH_MAX);
1040 printk(KERN_INFO PREFIX "Added _OSI(%s)\n", str);
1041 }
1042
1043 return 1;
1044}
1045
1046__setup("acpi_osi=", acpi_osi_setup);
1047
1048
1049static int __init acpi_serialize_setup(char *str)
1050{
1051 printk(KERN_INFO PREFIX "serialize enabled\n");
1052
1053 acpi_gbl_all_methods_serialized = TRUE;
1054
1055 return 1;
1056}
1057
1058__setup("acpi_serialize", acpi_serialize_setup);
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069static int __init acpi_wake_gpes_always_on_setup(char *str)
1070{
1071 printk(KERN_INFO PREFIX "wake GPEs not disabled\n");
1072
1073 acpi_gbl_leave_wake_gpes_disabled = FALSE;
1074
1075 return 1;
1076}
1077
1078__setup("acpi_wake_gpes_always_on", acpi_wake_gpes_always_on_setup);
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096#define ENFORCE_RESOURCES_STRICT 2
1097#define ENFORCE_RESOURCES_LAX 1
1098#define ENFORCE_RESOURCES_NO 0
1099
1100static unsigned int acpi_enforce_resources = ENFORCE_RESOURCES_STRICT;
1101
1102static int __init acpi_enforce_resources_setup(char *str)
1103{
1104 if (str == NULL || *str == '\0')
1105 return 0;
1106
1107 if (!strcmp("strict", str))
1108 acpi_enforce_resources = ENFORCE_RESOURCES_STRICT;
1109 else if (!strcmp("lax", str))
1110 acpi_enforce_resources = ENFORCE_RESOURCES_LAX;
1111 else if (!strcmp("no", str))
1112 acpi_enforce_resources = ENFORCE_RESOURCES_NO;
1113
1114 return 1;
1115}
1116
1117__setup("acpi_enforce_resources=", acpi_enforce_resources_setup);
1118
1119
1120
1121int acpi_check_resource_conflict(struct resource *res)
1122{
1123 struct acpi_res_list *res_list_elem;
1124 int ioport;
1125 int clash = 0;
1126
1127 if (acpi_enforce_resources == ENFORCE_RESOURCES_NO)
1128 return 0;
1129 if (!(res->flags & IORESOURCE_IO) && !(res->flags & IORESOURCE_MEM))
1130 return 0;
1131
1132 ioport = res->flags & IORESOURCE_IO;
1133
1134 spin_lock(&acpi_res_lock);
1135 list_for_each_entry(res_list_elem, &resource_list_head,
1136 resource_list) {
1137 if (ioport && (res_list_elem->resource_type
1138 != ACPI_ADR_SPACE_SYSTEM_IO))
1139 continue;
1140 if (!ioport && (res_list_elem->resource_type
1141 != ACPI_ADR_SPACE_SYSTEM_MEMORY))
1142 continue;
1143
1144 if (res->end < res_list_elem->start
1145 || res_list_elem->end < res->start)
1146 continue;
1147 clash = 1;
1148 break;
1149 }
1150 spin_unlock(&acpi_res_lock);
1151
1152 if (clash) {
1153 if (acpi_enforce_resources != ENFORCE_RESOURCES_NO) {
1154 printk("%sACPI: %s resource %s [0x%llx-0x%llx]"
1155 " conflicts with ACPI region %s"
1156 " [0x%llx-0x%llx]\n",
1157 acpi_enforce_resources == ENFORCE_RESOURCES_LAX
1158 ? KERN_WARNING : KERN_ERR,
1159 ioport ? "I/O" : "Memory", res->name,
1160 (long long) res->start, (long long) res->end,
1161 res_list_elem->name,
1162 (long long) res_list_elem->start,
1163 (long long) res_list_elem->end);
1164 if (acpi_enforce_resources == ENFORCE_RESOURCES_LAX)
1165 printk(KERN_NOTICE "ACPI: This conflict may"
1166 " cause random problems and system"
1167 " instability\n");
1168 printk(KERN_INFO "ACPI: If an ACPI driver is available"
1169 " for this device, you should use it instead of"
1170 " the native driver\n");
1171 }
1172 if (acpi_enforce_resources == ENFORCE_RESOURCES_STRICT)
1173 return -EBUSY;
1174 }
1175 return 0;
1176}
1177EXPORT_SYMBOL(acpi_check_resource_conflict);
1178
1179int acpi_check_region(resource_size_t start, resource_size_t n,
1180 const char *name)
1181{
1182 struct resource res = {
1183 .start = start,
1184 .end = start + n - 1,
1185 .name = name,
1186 .flags = IORESOURCE_IO,
1187 };
1188
1189 return acpi_check_resource_conflict(&res);
1190}
1191EXPORT_SYMBOL(acpi_check_region);
1192
1193int acpi_check_mem_region(resource_size_t start, resource_size_t n,
1194 const char *name)
1195{
1196 struct resource res = {
1197 .start = start,
1198 .end = start + n - 1,
1199 .name = name,
1200 .flags = IORESOURCE_MEM,
1201 };
1202
1203 return acpi_check_resource_conflict(&res);
1204
1205}
1206EXPORT_SYMBOL(acpi_check_mem_region);
1207
1208
1209
1210
1211
1212
1213
1214acpi_cpu_flags acpi_os_acquire_lock(acpi_spinlock lockp)
1215{
1216 acpi_cpu_flags flags;
1217 spin_lock_irqsave(lockp, flags);
1218 return flags;
1219}
1220
1221
1222
1223
1224
1225void acpi_os_release_lock(acpi_spinlock lockp, acpi_cpu_flags flags)
1226{
1227 spin_unlock_irqrestore(lockp, flags);
1228}
1229
1230#ifndef ACPI_USE_LOCAL_CACHE
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247acpi_status
1248acpi_os_create_cache(char *name, u16 size, u16 depth, acpi_cache_t ** cache)
1249{
1250 *cache = kmem_cache_create(name, size, 0, 0, NULL);
1251 if (*cache == NULL)
1252 return AE_ERROR;
1253 else
1254 return AE_OK;
1255}
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269acpi_status acpi_os_purge_cache(acpi_cache_t * cache)
1270{
1271 kmem_cache_shrink(cache);
1272 return (AE_OK);
1273}
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288acpi_status acpi_os_delete_cache(acpi_cache_t * cache)
1289{
1290 kmem_cache_destroy(cache);
1291 return (AE_OK);
1292}
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308acpi_status acpi_os_release_object(acpi_cache_t * cache, void *object)
1309{
1310 kmem_cache_free(cache, object);
1311 return (AE_OK);
1312}
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327acpi_status
1328acpi_os_validate_interface (char *interface)
1329{
1330 if (!strncmp(osi_additional_string, interface, OSI_STRING_LENGTH_MAX))
1331 return AE_OK;
1332 if (!strcmp("Linux", interface)) {
1333
1334 printk(KERN_NOTICE PREFIX
1335 "BIOS _OSI(Linux) query %s%s\n",
1336 osi_linux.enable ? "honored" : "ignored",
1337 osi_linux.cmdline ? " via cmdline" :
1338 osi_linux.dmi ? " via DMI" : "");
1339
1340 if (osi_linux.enable)
1341 return AE_OK;
1342 }
1343 return AE_SUPPORT;
1344}
1345
1346static inline int acpi_res_list_add(struct acpi_res_list *res)
1347{
1348 struct acpi_res_list *res_list_elem;
1349
1350 list_for_each_entry(res_list_elem, &resource_list_head,
1351 resource_list) {
1352
1353 if (res->resource_type == res_list_elem->resource_type &&
1354 res->start == res_list_elem->start &&
1355 res->end == res_list_elem->end) {
1356
1357
1358
1359
1360
1361
1362 res_list_elem->count++;
1363 return 0;
1364 }
1365 }
1366
1367 res->count = 1;
1368 list_add(&res->resource_list, &resource_list_head);
1369 return 1;
1370}
1371
1372static inline void acpi_res_list_del(struct acpi_res_list *res)
1373{
1374 struct acpi_res_list *res_list_elem;
1375
1376 list_for_each_entry(res_list_elem, &resource_list_head,
1377 resource_list) {
1378
1379 if (res->resource_type == res_list_elem->resource_type &&
1380 res->start == res_list_elem->start &&
1381 res->end == res_list_elem->end) {
1382
1383
1384
1385
1386
1387
1388 if (--res_list_elem->count == 0) {
1389 list_del(&res_list_elem->resource_list);
1390 kfree(res_list_elem);
1391 }
1392 return;
1393 }
1394 }
1395}
1396
1397acpi_status
1398acpi_os_invalidate_address(
1399 u8 space_id,
1400 acpi_physical_address address,
1401 acpi_size length)
1402{
1403 struct acpi_res_list res;
1404
1405 switch (space_id) {
1406 case ACPI_ADR_SPACE_SYSTEM_IO:
1407 case ACPI_ADR_SPACE_SYSTEM_MEMORY:
1408
1409
1410 res.start = address;
1411 res.end = address + length - 1;
1412 res.resource_type = space_id;
1413 spin_lock(&acpi_res_lock);
1414 acpi_res_list_del(&res);
1415 spin_unlock(&acpi_res_lock);
1416 break;
1417 case ACPI_ADR_SPACE_PCI_CONFIG:
1418 case ACPI_ADR_SPACE_EC:
1419 case ACPI_ADR_SPACE_SMBUS:
1420 case ACPI_ADR_SPACE_CMOS:
1421 case ACPI_ADR_SPACE_PCI_BAR_TARGET:
1422 case ACPI_ADR_SPACE_DATA_TABLE:
1423 case ACPI_ADR_SPACE_FIXED_HARDWARE:
1424 break;
1425 }
1426 return AE_OK;
1427}
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445acpi_status
1446acpi_os_validate_address (
1447 u8 space_id,
1448 acpi_physical_address address,
1449 acpi_size length,
1450 char *name)
1451{
1452 struct acpi_res_list *res;
1453 int added;
1454 if (acpi_enforce_resources == ENFORCE_RESOURCES_NO)
1455 return AE_OK;
1456
1457 switch (space_id) {
1458 case ACPI_ADR_SPACE_SYSTEM_IO:
1459 case ACPI_ADR_SPACE_SYSTEM_MEMORY:
1460
1461
1462 res = kzalloc(sizeof(struct acpi_res_list), GFP_KERNEL);
1463 if (!res)
1464 return AE_OK;
1465
1466 strlcpy(res->name, name, 5);
1467 res->start = address;
1468 res->end = address + length - 1;
1469 res->resource_type = space_id;
1470 spin_lock(&acpi_res_lock);
1471 added = acpi_res_list_add(res);
1472 spin_unlock(&acpi_res_lock);
1473 pr_debug("%s %s resource: start: 0x%llx, end: 0x%llx, "
1474 "name: %s\n", added ? "Added" : "Already exist",
1475 (space_id == ACPI_ADR_SPACE_SYSTEM_IO)
1476 ? "SystemIO" : "System Memory",
1477 (unsigned long long)res->start,
1478 (unsigned long long)res->end,
1479 res->name);
1480 if (!added)
1481 kfree(res);
1482 break;
1483 case ACPI_ADR_SPACE_PCI_CONFIG:
1484 case ACPI_ADR_SPACE_EC:
1485 case ACPI_ADR_SPACE_SMBUS:
1486 case ACPI_ADR_SPACE_CMOS:
1487 case ACPI_ADR_SPACE_PCI_BAR_TARGET:
1488 case ACPI_ADR_SPACE_DATA_TABLE:
1489 case ACPI_ADR_SPACE_FIXED_HARDWARE:
1490 break;
1491 }
1492 return AE_OK;
1493}
1494
1495#endif
1496