ACPI: basic initramfs DSDT override support
[linux-2.6-block.git] / drivers / acpi / osl.c
CommitLineData
1da177e4
LT
1/*
2 * acpi_osl.c - OS-dependent functions ($Revision: 83 $)
3 *
4 * Copyright (C) 2000 Andrew Henroid
5 * Copyright (C) 2001, 2002 Andy Grover <andrew.grover@intel.com>
6 * Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com>
7 *
8 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 *
24 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
25 *
26 */
27
1da177e4
LT
28#include <linux/module.h>
29#include <linux/kernel.h>
30#include <linux/slab.h>
31#include <linux/mm.h>
32#include <linux/pci.h>
1da177e4
LT
33#include <linux/interrupt.h>
34#include <linux/kmod.h>
35#include <linux/delay.h>
f507654d 36#include <linux/dmi.h>
1da177e4
LT
37#include <linux/workqueue.h>
38#include <linux/nmi.h>
ad71860a 39#include <linux/acpi.h>
1da177e4
LT
40#include <acpi/acpi.h>
41#include <asm/io.h>
42#include <acpi/acpi_bus.h>
43#include <acpi/processor.h>
44#include <asm/uaccess.h>
45
46#include <linux/efi.h>
47
1da177e4 48#define _COMPONENT ACPI_OS_SERVICES
f52fd66d 49ACPI_MODULE_NAME("osl");
1da177e4 50#define PREFIX "ACPI: "
4be44fcd
LB
51struct acpi_os_dpc {
52 acpi_osd_exec_callback function;
53 void *context;
65f27f38 54 struct work_struct work;
1da177e4
LT
55};
56
57#ifdef CONFIG_ACPI_CUSTOM_DSDT
58#include CONFIG_ACPI_CUSTOM_DSDT_FILE
59#endif
60
61#ifdef ENABLE_DEBUGGER
62#include <linux/kdb.h>
63
64/* stuff for debugger support */
65int acpi_in_debugger;
66EXPORT_SYMBOL(acpi_in_debugger);
67
68extern char line_buf[80];
4be44fcd 69#endif /*ENABLE_DEBUGGER */
1da177e4
LT
70
71static unsigned int acpi_irq_irq;
72static acpi_osd_handler acpi_irq_handler;
73static void *acpi_irq_context;
74static struct workqueue_struct *kacpid_wq;
88db5e14 75static struct workqueue_struct *kacpi_notify_wq;
1da177e4 76
ae00d812
LB
77#define OSI_STRING_LENGTH_MAX 64 /* arbitrary */
78static char osi_additional_string[OSI_STRING_LENGTH_MAX];
79
d4b7dc49
LB
80/*
81 * "Ode to _OSI(Linux)"
82 *
83 * osi_linux -- Control response to BIOS _OSI(Linux) query.
84 *
85 * As Linux evolves, the features that it supports change.
86 * So an OSI string such as "Linux" is not specific enough
87 * to be useful across multiple versions of Linux. It
88 * doesn't identify any particular feature, interface,
89 * or even any particular version of Linux...
90 *
91 * Unfortunately, Linux-2.6.22 and earlier responded "yes"
92 * to a BIOS _OSI(Linux) query. When
93 * a reference mobile BIOS started using it, its use
94 * started to spread to many vendor platforms.
95 * As it is not supportable, we need to halt that spread.
96 *
97 * Today, most BIOS references to _OSI(Linux) are noise --
98 * they have no functional effect and are just dead code
99 * carried over from the reference BIOS.
100 *
101 * The next most common case is that _OSI(Linux) harms Linux,
102 * usually by causing the BIOS to follow paths that are
103 * not tested during Windows validation.
104 *
105 * Finally, there is a short list of platforms
106 * where OSI(Linux) benefits Linux.
107 *
108 * In Linux-2.6.23, OSI(Linux) is first disabled by default.
109 * DMI is used to disable the dmesg warning about OSI(Linux)
110 * on platforms where it is known to have no effect.
111 * But a dmesg warning remains for systems where
112 * we do not know if OSI(Linux) is good or bad for the system.
113 * DMI is also used to enable OSI(Linux) for the machines
114 * that are known to need it.
115 *
116 * BIOS writers should NOT query _OSI(Linux) on future systems.
117 * It will be ignored by default, and to get Linux to
118 * not ignore it will require a kernel source update to
119 * add a DMI entry, or a boot-time "acpi_osi=Linux" invocation.
120 */
121#define OSI_LINUX_ENABLE 0
122
123struct osi_linux {
124 unsigned int enable:1;
125 unsigned int dmi:1;
126 unsigned int cmdline:1;
127 unsigned int known:1;
128} osi_linux = { OSI_LINUX_ENABLE, 0, 0, 0};
f507654d 129
9a47cdb1
BH
130static void __init acpi_request_region (struct acpi_generic_address *addr,
131 unsigned int length, char *desc)
132{
133 struct resource *res;
134
135 if (!addr->address || !length)
136 return;
137
eee3c859 138 if (addr->space_id == ACPI_ADR_SPACE_SYSTEM_IO)
9a47cdb1 139 res = request_region(addr->address, length, desc);
eee3c859 140 else if (addr->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY)
9a47cdb1
BH
141 res = request_mem_region(addr->address, length, desc);
142}
143
144static int __init acpi_reserve_resources(void)
145{
eee3c859 146 acpi_request_region(&acpi_gbl_FADT.xpm1a_event_block, acpi_gbl_FADT.pm1_event_length,
9a47cdb1
BH
147 "ACPI PM1a_EVT_BLK");
148
eee3c859 149 acpi_request_region(&acpi_gbl_FADT.xpm1b_event_block, acpi_gbl_FADT.pm1_event_length,
9a47cdb1
BH
150 "ACPI PM1b_EVT_BLK");
151
eee3c859 152 acpi_request_region(&acpi_gbl_FADT.xpm1a_control_block, acpi_gbl_FADT.pm1_control_length,
9a47cdb1
BH
153 "ACPI PM1a_CNT_BLK");
154
eee3c859 155 acpi_request_region(&acpi_gbl_FADT.xpm1b_control_block, acpi_gbl_FADT.pm1_control_length,
9a47cdb1
BH
156 "ACPI PM1b_CNT_BLK");
157
eee3c859
LB
158 if (acpi_gbl_FADT.pm_timer_length == 4)
159 acpi_request_region(&acpi_gbl_FADT.xpm_timer_block, 4, "ACPI PM_TMR");
9a47cdb1 160
eee3c859 161 acpi_request_region(&acpi_gbl_FADT.xpm2_control_block, acpi_gbl_FADT.pm2_control_length,
9a47cdb1
BH
162 "ACPI PM2_CNT_BLK");
163
164 /* Length of GPE blocks must be a non-negative multiple of 2 */
165
eee3c859
LB
166 if (!(acpi_gbl_FADT.gpe0_block_length & 0x1))
167 acpi_request_region(&acpi_gbl_FADT.xgpe0_block,
168 acpi_gbl_FADT.gpe0_block_length, "ACPI GPE0_BLK");
9a47cdb1 169
eee3c859
LB
170 if (!(acpi_gbl_FADT.gpe1_block_length & 0x1))
171 acpi_request_region(&acpi_gbl_FADT.xgpe1_block,
172 acpi_gbl_FADT.gpe1_block_length, "ACPI GPE1_BLK");
9a47cdb1
BH
173
174 return 0;
175}
176device_initcall(acpi_reserve_resources);
177
dd272b57 178acpi_status __init acpi_os_initialize(void)
1da177e4
LT
179{
180 return AE_OK;
181}
182
4be44fcd 183acpi_status acpi_os_initialize1(void)
1da177e4
LT
184{
185 /*
186 * Initialize PCI configuration space access, as we'll need to access
187 * it while walking the namespace (bus 0 and root bridges w/ _BBNs).
188 */
1da177e4 189 if (!raw_pci_ops) {
4be44fcd
LB
190 printk(KERN_ERR PREFIX
191 "Access to PCI configuration space unavailable\n");
1da177e4
LT
192 return AE_NULL_ENTRY;
193 }
1da177e4 194 kacpid_wq = create_singlethread_workqueue("kacpid");
88db5e14 195 kacpi_notify_wq = create_singlethread_workqueue("kacpi_notify");
1da177e4 196 BUG_ON(!kacpid_wq);
88db5e14 197 BUG_ON(!kacpi_notify_wq);
1da177e4
LT
198 return AE_OK;
199}
200
4be44fcd 201acpi_status acpi_os_terminate(void)
1da177e4
LT
202{
203 if (acpi_irq_handler) {
204 acpi_os_remove_interrupt_handler(acpi_irq_irq,
205 acpi_irq_handler);
206 }
207
208 destroy_workqueue(kacpid_wq);
88db5e14 209 destroy_workqueue(kacpi_notify_wq);
1da177e4
LT
210
211 return AE_OK;
212}
213
4be44fcd 214void acpi_os_printf(const char *fmt, ...)
1da177e4
LT
215{
216 va_list args;
217 va_start(args, fmt);
218 acpi_os_vprintf(fmt, args);
219 va_end(args);
220}
4be44fcd 221
1da177e4
LT
222EXPORT_SYMBOL(acpi_os_printf);
223
4be44fcd 224void acpi_os_vprintf(const char *fmt, va_list args)
1da177e4
LT
225{
226 static char buffer[512];
4be44fcd 227
1da177e4
LT
228 vsprintf(buffer, fmt, args);
229
230#ifdef ENABLE_DEBUGGER
231 if (acpi_in_debugger) {
232 kdb_printf("%s", buffer);
233 } else {
234 printk("%s", buffer);
235 }
236#else
237 printk("%s", buffer);
238#endif
239}
240
ad71860a 241acpi_physical_address __init acpi_os_get_root_pointer(void)
1da177e4
LT
242{
243 if (efi_enabled) {
b2c99e3c 244 if (efi.acpi20 != EFI_INVALID_TABLE_ADDR)
ad71860a 245 return efi.acpi20;
b2c99e3c 246 else if (efi.acpi != EFI_INVALID_TABLE_ADDR)
ad71860a 247 return efi.acpi;
1da177e4 248 else {
4be44fcd
LB
249 printk(KERN_ERR PREFIX
250 "System description tables not found\n");
ad71860a 251 return 0;
1da177e4 252 }
ad71860a
AS
253 } else
254 return acpi_find_rsdp();
1da177e4
LT
255}
256
ad71860a 257void __iomem *acpi_os_map_memory(acpi_physical_address phys, acpi_size size)
1da177e4 258{
9f4fd61f
BH
259 if (phys > ULONG_MAX) {
260 printk(KERN_ERR PREFIX "Cannot map memory that high\n");
70c0846e 261 return NULL;
1da177e4 262 }
ad71860a
AS
263 if (acpi_gbl_permanent_mmap)
264 /*
265 * ioremap checks to ensure this is in reserved space
266 */
267 return ioremap((unsigned long)phys, size);
268 else
269 return __acpi_map_table((unsigned long)phys, size);
1da177e4 270}
55a82ab3 271EXPORT_SYMBOL_GPL(acpi_os_map_memory);
1da177e4 272
4be44fcd 273void acpi_os_unmap_memory(void __iomem * virt, acpi_size size)
1da177e4 274{
ad71860a
AS
275 if (acpi_gbl_permanent_mmap) {
276 iounmap(virt);
277 }
1da177e4 278}
55a82ab3 279EXPORT_SYMBOL_GPL(acpi_os_unmap_memory);
1da177e4
LT
280
281#ifdef ACPI_FUTURE_USAGE
282acpi_status
4be44fcd 283acpi_os_get_physical_address(void *virt, acpi_physical_address * phys)
1da177e4 284{
4be44fcd 285 if (!phys || !virt)
1da177e4
LT
286 return AE_BAD_PARAMETER;
287
288 *phys = virt_to_phys(virt);
289
290 return AE_OK;
291}
292#endif
293
294#define ACPI_MAX_OVERRIDE_LEN 100
295
296static char acpi_os_name[ACPI_MAX_OVERRIDE_LEN];
297
298acpi_status
4be44fcd
LB
299acpi_os_predefined_override(const struct acpi_predefined_names *init_val,
300 acpi_string * new_val)
1da177e4
LT
301{
302 if (!init_val || !new_val)
303 return AE_BAD_PARAMETER;
304
305 *new_val = NULL;
4be44fcd 306 if (!memcmp(init_val->name, "_OS_", 4) && strlen(acpi_os_name)) {
1da177e4 307 printk(KERN_INFO PREFIX "Overriding _OS definition to '%s'\n",
4be44fcd 308 acpi_os_name);
1da177e4
LT
309 *new_val = acpi_os_name;
310 }
311
312 return AE_OK;
313}
314
71fc47a9
MG
315#ifdef CONFIG_ACPI_CUSTOM_DSDT_INITRD
316struct acpi_table_header *acpi_find_dsdt_initrd(void)
317{
318 struct file *firmware_file;
319 mm_segment_t oldfs;
320 unsigned long len, len2;
321 struct acpi_table_header *dsdt_buffer, *ret = NULL;
322 struct kstat stat;
323 char *ramfs_dsdt_name = "/DSDT.aml";
324
325 printk(KERN_INFO PREFIX "Looking for DSDT in initramfs... ");
326
327 /*
328 * Never do this at home, only the user-space is allowed to open a file.
329 * The clean way would be to use the firmware loader. But this code must be run
330 * before there is any userspace available. So we need a static/init firmware
331 * infrastructure, which doesn't exist yet...
332 */
333 if (vfs_stat(ramfs_dsdt_name, &stat) < 0) {
334 printk("not found.\n");
335 return ret;
336 }
337
338 len = stat.size;
339 /* check especially against empty files */
340 if (len <= 4) {
341 printk("error, file is too small: only %lu bytes.\n", len);
342 return ret;
343 }
344
345 firmware_file = filp_open(ramfs_dsdt_name, O_RDONLY, 0);
346 if (IS_ERR(firmware_file)) {
347 printk("error, could not open file %s.\n", ramfs_dsdt_name);
348 return ret;
349 }
350
351 dsdt_buffer = ACPI_ALLOCATE(len);
352 if (!dsdt_buffer) {
353 printk("error when allocating %lu bytes of memory.\n", len);
354 goto err;
355 }
356
357 oldfs = get_fs();
358 set_fs(KERNEL_DS);
359 len2 = vfs_read(firmware_file, (char __user *)dsdt_buffer, len, &firmware_file->f_pos);
360 set_fs(oldfs);
361 if (len2 < len) {
362 printk("error trying to read %lu bytes from %s.\n", len, ramfs_dsdt_name);
363 ACPI_FREE(dsdt_buffer);
364 goto err;
365 }
366
367 printk("successfully read %lu bytes from %s.\n", len, ramfs_dsdt_name);
368 ret = dsdt_buffer;
369err:
370 filp_close(firmware_file, NULL);
371 return ret;
372}
373#endif
374
1da177e4 375acpi_status
4be44fcd
LB
376acpi_os_table_override(struct acpi_table_header * existing_table,
377 struct acpi_table_header ** new_table)
1da177e4
LT
378{
379 if (!existing_table || !new_table)
380 return AE_BAD_PARAMETER;
381
71fc47a9
MG
382 *new_table = NULL;
383
1da177e4
LT
384#ifdef CONFIG_ACPI_CUSTOM_DSDT
385 if (strncmp(existing_table->signature, "DSDT", 4) == 0)
4be44fcd 386 *new_table = (struct acpi_table_header *)AmlCode;
71fc47a9
MG
387#endif
388#ifdef CONFIG_ACPI_CUSTOM_DSDT_INITRD
389 if (strncmp(existing_table->signature, "DSDT", 4) == 0) {
390 struct acpi_table_header *initrd_table = acpi_find_dsdt_initrd();
391 if (initrd_table)
392 *new_table = initrd_table;
393 }
1da177e4
LT
394#endif
395 return AE_OK;
396}
397
7d12e780 398static irqreturn_t acpi_irq(int irq, void *dev_id)
1da177e4 399{
4be44fcd 400 return (*acpi_irq_handler) (acpi_irq_context) ? IRQ_HANDLED : IRQ_NONE;
1da177e4
LT
401}
402
403acpi_status
4be44fcd
LB
404acpi_os_install_interrupt_handler(u32 gsi, acpi_osd_handler handler,
405 void *context)
1da177e4
LT
406{
407 unsigned int irq;
408
409 /*
410 * Ignore the GSI from the core, and use the value in our copy of the
411 * FADT. It may not be the same if an interrupt source override exists
412 * for the SCI.
413 */
cee324b1 414 gsi = acpi_gbl_FADT.sci_interrupt;
1da177e4
LT
415 if (acpi_gsi_to_irq(gsi, &irq) < 0) {
416 printk(KERN_ERR PREFIX "SCI (ACPI GSI %d) not registered\n",
417 gsi);
418 return AE_OK;
419 }
420
421 acpi_irq_handler = handler;
422 acpi_irq_context = context;
dace1453 423 if (request_irq(irq, acpi_irq, IRQF_SHARED, "acpi", acpi_irq)) {
1da177e4
LT
424 printk(KERN_ERR PREFIX "SCI (IRQ%d) allocation failed\n", irq);
425 return AE_NOT_ACQUIRED;
426 }
427 acpi_irq_irq = irq;
428
429 return AE_OK;
430}
431
4be44fcd 432acpi_status acpi_os_remove_interrupt_handler(u32 irq, acpi_osd_handler handler)
1da177e4
LT
433{
434 if (irq) {
435 free_irq(irq, acpi_irq);
436 acpi_irq_handler = NULL;
437 acpi_irq_irq = 0;
438 }
439
440 return AE_OK;
441}
442
443/*
444 * Running in interpreter thread context, safe to sleep
445 */
446
4be44fcd 447void acpi_os_sleep(acpi_integer ms)
1da177e4 448{
01a527ec 449 schedule_timeout_interruptible(msecs_to_jiffies(ms));
1da177e4 450}
4be44fcd 451
1da177e4
LT
452EXPORT_SYMBOL(acpi_os_sleep);
453
4be44fcd 454void acpi_os_stall(u32 us)
1da177e4
LT
455{
456 while (us) {
457 u32 delay = 1000;
458
459 if (delay > us)
460 delay = us;
461 udelay(delay);
462 touch_nmi_watchdog();
463 us -= delay;
464 }
465}
4be44fcd 466
1da177e4
LT
467EXPORT_SYMBOL(acpi_os_stall);
468
469/*
470 * Support ACPI 3.0 AML Timer operand
471 * Returns 64-bit free-running, monotonically increasing timer
472 * with 100ns granularity
473 */
4be44fcd 474u64 acpi_os_get_timer(void)
1da177e4
LT
475{
476 static u64 t;
477
478#ifdef CONFIG_HPET
479 /* TBD: use HPET if available */
480#endif
481
482#ifdef CONFIG_X86_PM_TIMER
483 /* TBD: default to PM timer if HPET was not available */
484#endif
485 if (!t)
486 printk(KERN_ERR PREFIX "acpi_os_get_timer() TBD\n");
487
488 return ++t;
489}
490
4be44fcd 491acpi_status acpi_os_read_port(acpi_io_address port, u32 * value, u32 width)
1da177e4
LT
492{
493 u32 dummy;
494
495 if (!value)
496 value = &dummy;
497
49fbabf5
ZY
498 *value = 0;
499 if (width <= 8) {
4be44fcd 500 *(u8 *) value = inb(port);
49fbabf5 501 } else if (width <= 16) {
4be44fcd 502 *(u16 *) value = inw(port);
49fbabf5 503 } else if (width <= 32) {
4be44fcd 504 *(u32 *) value = inl(port);
49fbabf5 505 } else {
1da177e4
LT
506 BUG();
507 }
508
509 return AE_OK;
510}
4be44fcd 511
1da177e4
LT
512EXPORT_SYMBOL(acpi_os_read_port);
513
4be44fcd 514acpi_status acpi_os_write_port(acpi_io_address port, u32 value, u32 width)
1da177e4 515{
49fbabf5 516 if (width <= 8) {
1da177e4 517 outb(value, port);
49fbabf5 518 } else if (width <= 16) {
1da177e4 519 outw(value, port);
49fbabf5 520 } else if (width <= 32) {
1da177e4 521 outl(value, port);
49fbabf5 522 } else {
1da177e4
LT
523 BUG();
524 }
525
526 return AE_OK;
527}
4be44fcd 528
1da177e4
LT
529EXPORT_SYMBOL(acpi_os_write_port);
530
531acpi_status
4be44fcd 532acpi_os_read_memory(acpi_physical_address phys_addr, u32 * value, u32 width)
1da177e4 533{
4be44fcd
LB
534 u32 dummy;
535 void __iomem *virt_addr;
1da177e4 536
9f4fd61f 537 virt_addr = ioremap(phys_addr, width);
1da177e4
LT
538 if (!value)
539 value = &dummy;
540
541 switch (width) {
542 case 8:
4be44fcd 543 *(u8 *) value = readb(virt_addr);
1da177e4
LT
544 break;
545 case 16:
4be44fcd 546 *(u16 *) value = readw(virt_addr);
1da177e4
LT
547 break;
548 case 32:
4be44fcd 549 *(u32 *) value = readl(virt_addr);
1da177e4
LT
550 break;
551 default:
552 BUG();
553 }
554
9f4fd61f 555 iounmap(virt_addr);
1da177e4
LT
556
557 return AE_OK;
558}
559
560acpi_status
4be44fcd 561acpi_os_write_memory(acpi_physical_address phys_addr, u32 value, u32 width)
1da177e4 562{
4be44fcd 563 void __iomem *virt_addr;
1da177e4 564
9f4fd61f 565 virt_addr = ioremap(phys_addr, width);
1da177e4
LT
566
567 switch (width) {
568 case 8:
569 writeb(value, virt_addr);
570 break;
571 case 16:
572 writew(value, virt_addr);
573 break;
574 case 32:
575 writel(value, virt_addr);
576 break;
577 default:
578 BUG();
579 }
580
9f4fd61f 581 iounmap(virt_addr);
1da177e4
LT
582
583 return AE_OK;
584}
585
1da177e4 586acpi_status
4be44fcd
LB
587acpi_os_read_pci_configuration(struct acpi_pci_id * pci_id, u32 reg,
588 void *value, u32 width)
1da177e4
LT
589{
590 int result, size;
591
592 if (!value)
593 return AE_BAD_PARAMETER;
594
595 switch (width) {
596 case 8:
597 size = 1;
598 break;
599 case 16:
600 size = 2;
601 break;
602 case 32:
603 size = 4;
604 break;
605 default:
606 return AE_ERROR;
607 }
608
609 BUG_ON(!raw_pci_ops);
610
611 result = raw_pci_ops->read(pci_id->segment, pci_id->bus,
4be44fcd
LB
612 PCI_DEVFN(pci_id->device, pci_id->function),
613 reg, size, value);
1da177e4
LT
614
615 return (result ? AE_ERROR : AE_OK);
616}
4be44fcd 617
1da177e4
LT
618EXPORT_SYMBOL(acpi_os_read_pci_configuration);
619
620acpi_status
4be44fcd
LB
621acpi_os_write_pci_configuration(struct acpi_pci_id * pci_id, u32 reg,
622 acpi_integer value, u32 width)
1da177e4
LT
623{
624 int result, size;
625
626 switch (width) {
627 case 8:
628 size = 1;
629 break;
630 case 16:
631 size = 2;
632 break;
633 case 32:
634 size = 4;
635 break;
636 default:
637 return AE_ERROR;
638 }
639
640 BUG_ON(!raw_pci_ops);
641
642 result = raw_pci_ops->write(pci_id->segment, pci_id->bus,
4be44fcd
LB
643 PCI_DEVFN(pci_id->device, pci_id->function),
644 reg, size, value);
1da177e4
LT
645
646 return (result ? AE_ERROR : AE_OK);
647}
648
649/* TODO: Change code to take advantage of driver model more */
4be44fcd
LB
650static void acpi_os_derive_pci_id_2(acpi_handle rhandle, /* upper bound */
651 acpi_handle chandle, /* current node */
652 struct acpi_pci_id **id,
653 int *is_bridge, u8 * bus_number)
1da177e4 654{
4be44fcd
LB
655 acpi_handle handle;
656 struct acpi_pci_id *pci_id = *id;
657 acpi_status status;
658 unsigned long temp;
659 acpi_object_type type;
660 u8 tu8;
1da177e4
LT
661
662 acpi_get_parent(chandle, &handle);
663 if (handle != rhandle) {
4be44fcd
LB
664 acpi_os_derive_pci_id_2(rhandle, handle, &pci_id, is_bridge,
665 bus_number);
1da177e4
LT
666
667 status = acpi_get_type(handle, &type);
4be44fcd 668 if ((ACPI_FAILURE(status)) || (type != ACPI_TYPE_DEVICE))
1da177e4
LT
669 return;
670
4be44fcd
LB
671 status =
672 acpi_evaluate_integer(handle, METHOD_NAME__ADR, NULL,
673 &temp);
1da177e4 674 if (ACPI_SUCCESS(status)) {
4be44fcd
LB
675 pci_id->device = ACPI_HIWORD(ACPI_LODWORD(temp));
676 pci_id->function = ACPI_LOWORD(ACPI_LODWORD(temp));
1da177e4
LT
677
678 if (*is_bridge)
679 pci_id->bus = *bus_number;
680
681 /* any nicer way to get bus number of bridge ? */
4be44fcd
LB
682 status =
683 acpi_os_read_pci_configuration(pci_id, 0x0e, &tu8,
684 8);
685 if (ACPI_SUCCESS(status)
686 && ((tu8 & 0x7f) == 1 || (tu8 & 0x7f) == 2)) {
687 status =
688 acpi_os_read_pci_configuration(pci_id, 0x18,
689 &tu8, 8);
1da177e4
LT
690 if (!ACPI_SUCCESS(status)) {
691 /* Certainly broken... FIX ME */
692 return;
693 }
694 *is_bridge = 1;
695 pci_id->bus = tu8;
4be44fcd
LB
696 status =
697 acpi_os_read_pci_configuration(pci_id, 0x19,
698 &tu8, 8);
1da177e4
LT
699 if (ACPI_SUCCESS(status)) {
700 *bus_number = tu8;
701 }
702 } else
703 *is_bridge = 0;
704 }
705 }
706}
707
4be44fcd
LB
708void acpi_os_derive_pci_id(acpi_handle rhandle, /* upper bound */
709 acpi_handle chandle, /* current node */
710 struct acpi_pci_id **id)
1da177e4
LT
711{
712 int is_bridge = 1;
713 u8 bus_number = (*id)->bus;
714
715 acpi_os_derive_pci_id_2(rhandle, chandle, id, &is_bridge, &bus_number);
716}
717
65f27f38 718static void acpi_os_execute_deferred(struct work_struct *work)
88db5e14
AS
719{
720 struct acpi_os_dpc *dpc = container_of(work, struct acpi_os_dpc, work);
721 if (!dpc) {
722 printk(KERN_ERR PREFIX "Invalid (NULL) context\n");
723 return;
724 }
725
726 dpc->function(dpc->context);
727 kfree(dpc);
728
729 /* Yield cpu to notify thread */
730 cond_resched();
731
732 return;
733}
734
735static void acpi_os_execute_notify(struct work_struct *work)
1da177e4 736{
65f27f38 737 struct acpi_os_dpc *dpc = container_of(work, struct acpi_os_dpc, work);
1da177e4 738
1da177e4 739 if (!dpc) {
6468463a 740 printk(KERN_ERR PREFIX "Invalid (NULL) context\n");
d550d98d 741 return;
1da177e4
LT
742 }
743
744 dpc->function(dpc->context);
745
746 kfree(dpc);
747
d550d98d 748 return;
1da177e4
LT
749}
750
b8d35192
AS
751/*******************************************************************************
752 *
753 * FUNCTION: acpi_os_execute
754 *
755 * PARAMETERS: Type - Type of the callback
756 * Function - Function to be executed
757 * Context - Function parameters
758 *
759 * RETURN: Status
760 *
761 * DESCRIPTION: Depending on type, either queues function for deferred execution or
762 * immediately executes function on a separate thread.
763 *
764 ******************************************************************************/
765
766acpi_status acpi_os_execute(acpi_execute_type type,
4be44fcd 767 acpi_osd_exec_callback function, void *context)
1da177e4 768{
4be44fcd
LB
769 acpi_status status = AE_OK;
770 struct acpi_os_dpc *dpc;
72945b2b 771
72945b2b
LB
772 ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
773 "Scheduling function [%p(%p)] for deferred execution.\n",
774 function, context));
1da177e4
LT
775
776 if (!function)
88db5e14 777 return AE_BAD_PARAMETER;
72945b2b 778
1da177e4
LT
779 /*
780 * Allocate/initialize DPC structure. Note that this memory will be
65f27f38 781 * freed by the callee. The kernel handles the work_struct list in a
1da177e4
LT
782 * way that allows us to also free its memory inside the callee.
783 * Because we may want to schedule several tasks with different
784 * parameters we can't use the approach some kernel code uses of
65f27f38 785 * having a static work_struct.
1da177e4 786 */
72945b2b 787
65f27f38 788 dpc = kmalloc(sizeof(struct acpi_os_dpc), GFP_ATOMIC);
1da177e4 789 if (!dpc)
b976fe19
LT
790 return_ACPI_STATUS(AE_NO_MEMORY);
791
1da177e4
LT
792 dpc->function = function;
793 dpc->context = context;
b976fe19 794
88db5e14
AS
795 if (type == OSL_NOTIFY_HANDLER) {
796 INIT_WORK(&dpc->work, acpi_os_execute_notify);
797 if (!queue_work(kacpi_notify_wq, &dpc->work)) {
798 status = AE_ERROR;
799 kfree(dpc);
800 }
801 } else {
802 INIT_WORK(&dpc->work, acpi_os_execute_deferred);
803 if (!queue_work(kacpid_wq, &dpc->work)) {
804 ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
b976fe19 805 "Call to queue_work() failed.\n"));
88db5e14
AS
806 status = AE_ERROR;
807 kfree(dpc);
808 }
1da177e4 809 }
b976fe19 810 return_ACPI_STATUS(status);
1da177e4 811}
4be44fcd 812
b8d35192 813EXPORT_SYMBOL(acpi_os_execute);
1da177e4 814
4be44fcd 815void acpi_os_wait_events_complete(void *context)
1da177e4
LT
816{
817 flush_workqueue(kacpid_wq);
818}
4be44fcd 819
1da177e4
LT
820EXPORT_SYMBOL(acpi_os_wait_events_complete);
821
822/*
823 * Allocate the memory for a spinlock and initialize it.
824 */
967440e3 825acpi_status acpi_os_create_lock(acpi_spinlock * handle)
1da177e4 826{
967440e3 827 spin_lock_init(*handle);
1da177e4 828
d550d98d 829 return AE_OK;
1da177e4
LT
830}
831
1da177e4
LT
832/*
833 * Deallocate the memory for a spinlock.
834 */
967440e3 835void acpi_os_delete_lock(acpi_spinlock handle)
1da177e4 836{
d550d98d 837 return;
1da177e4
LT
838}
839
1da177e4 840acpi_status
4be44fcd 841acpi_os_create_semaphore(u32 max_units, u32 initial_units, acpi_handle * handle)
1da177e4 842{
4be44fcd 843 struct semaphore *sem = NULL;
1da177e4 844
1da177e4
LT
845
846 sem = acpi_os_allocate(sizeof(struct semaphore));
847 if (!sem)
d550d98d 848 return AE_NO_MEMORY;
1da177e4
LT
849 memset(sem, 0, sizeof(struct semaphore));
850
851 sema_init(sem, initial_units);
852
4be44fcd 853 *handle = (acpi_handle *) sem;
1da177e4 854
4be44fcd
LB
855 ACPI_DEBUG_PRINT((ACPI_DB_MUTEX, "Creating semaphore[%p|%d].\n",
856 *handle, initial_units));
1da177e4 857
d550d98d 858 return AE_OK;
1da177e4 859}
1da177e4 860
4be44fcd 861EXPORT_SYMBOL(acpi_os_create_semaphore);
1da177e4
LT
862
863/*
864 * TODO: A better way to delete semaphores? Linux doesn't have a
865 * 'delete_semaphore()' function -- may result in an invalid
866 * pointer dereference for non-synchronized consumers. Should
867 * we at least check for blocked threads and signal/cancel them?
868 */
869
4be44fcd 870acpi_status acpi_os_delete_semaphore(acpi_handle handle)
1da177e4 871{
4be44fcd 872 struct semaphore *sem = (struct semaphore *)handle;
1da177e4 873
1da177e4
LT
874
875 if (!sem)
d550d98d 876 return AE_BAD_PARAMETER;
1da177e4 877
4be44fcd 878 ACPI_DEBUG_PRINT((ACPI_DB_MUTEX, "Deleting semaphore[%p].\n", handle));
1da177e4 879
02438d87 880 kfree(sem);
4be44fcd 881 sem = NULL;
1da177e4 882
d550d98d 883 return AE_OK;
1da177e4 884}
1da177e4 885
4be44fcd 886EXPORT_SYMBOL(acpi_os_delete_semaphore);
1da177e4
LT
887
888/*
889 * TODO: The kernel doesn't have a 'down_timeout' function -- had to
890 * improvise. The process is to sleep for one scheduler quantum
891 * until the semaphore becomes available. Downside is that this
892 * may result in starvation for timeout-based waits when there's
893 * lots of semaphore activity.
894 *
895 * TODO: Support for units > 1?
896 */
4be44fcd 897acpi_status acpi_os_wait_semaphore(acpi_handle handle, u32 units, u16 timeout)
1da177e4 898{
4be44fcd
LB
899 acpi_status status = AE_OK;
900 struct semaphore *sem = (struct semaphore *)handle;
901 int ret = 0;
1da177e4 902
1da177e4
LT
903
904 if (!sem || (units < 1))
d550d98d 905 return AE_BAD_PARAMETER;
1da177e4
LT
906
907 if (units > 1)
d550d98d 908 return AE_SUPPORT;
1da177e4 909
4be44fcd
LB
910 ACPI_DEBUG_PRINT((ACPI_DB_MUTEX, "Waiting for semaphore[%p|%d|%d]\n",
911 handle, units, timeout));
1da177e4 912
d68909f4
LB
913 /*
914 * This can be called during resume with interrupts off.
915 * Like boot-time, we should be single threaded and will
916 * always get the lock if we try -- timeout or not.
917 * If this doesn't succeed, then we will oops courtesy of
918 * might_sleep() in down().
919 */
920 if (!down_trylock(sem))
921 return AE_OK;
922
4be44fcd 923 switch (timeout) {
1da177e4
LT
924 /*
925 * No Wait:
926 * --------
927 * A zero timeout value indicates that we shouldn't wait - just
928 * acquire the semaphore if available otherwise return AE_TIME
929 * (a.k.a. 'would block').
930 */
4be44fcd
LB
931 case 0:
932 if (down_trylock(sem))
1da177e4
LT
933 status = AE_TIME;
934 break;
935
936 /*
937 * Wait Indefinitely:
938 * ------------------
939 */
4be44fcd 940 case ACPI_WAIT_FOREVER:
1da177e4
LT
941 down(sem);
942 break;
943
944 /*
945 * Wait w/ Timeout:
946 * ----------------
947 */
4be44fcd 948 default:
1da177e4
LT
949 // TODO: A better timeout algorithm?
950 {
951 int i = 0;
4be44fcd 952 static const int quantum_ms = 1000 / HZ;
1da177e4
LT
953
954 ret = down_trylock(sem);
dacd9b80 955 for (i = timeout; (i > 0 && ret != 0); i -= quantum_ms) {
01a527ec 956 schedule_timeout_interruptible(1);
1da177e4
LT
957 ret = down_trylock(sem);
958 }
4be44fcd 959
1da177e4
LT
960 if (ret != 0)
961 status = AE_TIME;
962 }
963 break;
964 }
965
966 if (ACPI_FAILURE(status)) {
9e7e2c04 967 ACPI_DEBUG_PRINT((ACPI_DB_MUTEX,
a6fc6720 968 "Failed to acquire semaphore[%p|%d|%d], %s",
4be44fcd
LB
969 handle, units, timeout,
970 acpi_format_exception(status)));
971 } else {
972 ACPI_DEBUG_PRINT((ACPI_DB_MUTEX,
a6fc6720 973 "Acquired semaphore[%p|%d|%d]", handle,
4be44fcd 974 units, timeout));
1da177e4
LT
975 }
976
d550d98d 977 return status;
1da177e4 978}
1da177e4 979
4be44fcd 980EXPORT_SYMBOL(acpi_os_wait_semaphore);
1da177e4
LT
981
982/*
983 * TODO: Support for units > 1?
984 */
4be44fcd 985acpi_status acpi_os_signal_semaphore(acpi_handle handle, u32 units)
1da177e4 986{
4be44fcd 987 struct semaphore *sem = (struct semaphore *)handle;
1da177e4 988
1da177e4
LT
989
990 if (!sem || (units < 1))
d550d98d 991 return AE_BAD_PARAMETER;
1da177e4
LT
992
993 if (units > 1)
d550d98d 994 return AE_SUPPORT;
1da177e4 995
4be44fcd
LB
996 ACPI_DEBUG_PRINT((ACPI_DB_MUTEX, "Signaling semaphore[%p|%d]\n", handle,
997 units));
1da177e4
LT
998
999 up(sem);
1000
d550d98d 1001 return AE_OK;
1da177e4 1002}
4be44fcd 1003
1da177e4
LT
1004EXPORT_SYMBOL(acpi_os_signal_semaphore);
1005
1006#ifdef ACPI_FUTURE_USAGE
4be44fcd 1007u32 acpi_os_get_line(char *buffer)
1da177e4
LT
1008{
1009
1010#ifdef ENABLE_DEBUGGER
1011 if (acpi_in_debugger) {
1012 u32 chars;
1013
1014 kdb_read(buffer, sizeof(line_buf));
1015
1016 /* remove the CR kdb includes */
1017 chars = strlen(buffer) - 1;
1018 buffer[chars] = '\0';
1019 }
1020#endif
1021
1022 return 0;
1023}
4be44fcd 1024#endif /* ACPI_FUTURE_USAGE */
1da177e4 1025
4be44fcd 1026acpi_status acpi_os_signal(u32 function, void *info)
1da177e4 1027{
4be44fcd 1028 switch (function) {
1da177e4
LT
1029 case ACPI_SIGNAL_FATAL:
1030 printk(KERN_ERR PREFIX "Fatal opcode executed\n");
1031 break;
1032 case ACPI_SIGNAL_BREAKPOINT:
1033 /*
1034 * AML Breakpoint
1035 * ACPI spec. says to treat it as a NOP unless
1036 * you are debugging. So if/when we integrate
1037 * AML debugger into the kernel debugger its
1038 * hook will go here. But until then it is
1039 * not useful to print anything on breakpoints.
1040 */
1041 break;
1042 default:
1043 break;
1044 }
1045
1046 return AE_OK;
1047}
4be44fcd 1048
1da177e4
LT
1049EXPORT_SYMBOL(acpi_os_signal);
1050
4be44fcd 1051static int __init acpi_os_name_setup(char *str)
1da177e4
LT
1052{
1053 char *p = acpi_os_name;
4be44fcd 1054 int count = ACPI_MAX_OVERRIDE_LEN - 1;
1da177e4
LT
1055
1056 if (!str || !*str)
1057 return 0;
1058
1059 for (; count-- && str && *str; str++) {
1060 if (isalnum(*str) || *str == ' ' || *str == ':')
1061 *p++ = *str;
1062 else if (*str == '\'' || *str == '"')
1063 continue;
1064 else
1065 break;
1066 }
1067 *p = 0;
1068
1069 return 1;
4be44fcd 1070
1da177e4
LT
1071}
1072
1073__setup("acpi_os_name=", acpi_os_name_setup);
1074
d4b7dc49
LB
1075static void __init set_osi_linux(unsigned int enable)
1076{
1077 if (osi_linux.enable != enable) {
1078 osi_linux.enable = enable;
1079 printk(KERN_NOTICE PREFIX "%sed _OSI(Linux)\n",
1080 enable ? "Add": "Delet");
1081 }
1082 return;
1083}
1084
1085static void __init acpi_cmdline_osi_linux(unsigned int enable)
1086{
1087 osi_linux.cmdline = 1; /* cmdline set the default */
1088 set_osi_linux(enable);
1089
1090 return;
1091}
1092
1093void __init acpi_dmi_osi_linux(int enable, const struct dmi_system_id *d)
1094{
1095 osi_linux.dmi = 1; /* DMI knows that this box asks OSI(Linux) */
1096
1097 printk(KERN_NOTICE PREFIX "DMI detected: %s\n", d->ident);
1098
1099 if (enable == -1)
1100 return;
1101
1102 osi_linux.known = 1; /* DMI knows which OSI(Linux) default needed */
f507654d 1103
d4b7dc49 1104 set_osi_linux(enable);
f507654d 1105
f507654d
LB
1106 return;
1107}
1108
1da177e4 1109/*
ae00d812
LB
1110 * Modify the list of "OS Interfaces" reported to BIOS via _OSI
1111 *
1da177e4 1112 * empty string disables _OSI
ae00d812
LB
1113 * string starting with '!' disables that string
1114 * otherwise string is added to list, augmenting built-in strings
1da177e4 1115 */
4be44fcd 1116static int __init acpi_osi_setup(char *str)
1da177e4
LT
1117{
1118 if (str == NULL || *str == '\0') {
1119 printk(KERN_INFO PREFIX "_OSI method disabled\n");
1120 acpi_gbl_create_osi_method = FALSE;
aa2e09da 1121 } else if (!strcmp("!Linux", str)) {
d4b7dc49 1122 acpi_cmdline_osi_linux(0); /* !enable */
ae00d812
LB
1123 } else if (*str == '!') {
1124 if (acpi_osi_invalidate(++str) == AE_OK)
1125 printk(KERN_INFO PREFIX "Deleted _OSI(%s)\n", str);
f507654d 1126 } else if (!strcmp("Linux", str)) {
d4b7dc49 1127 acpi_cmdline_osi_linux(1); /* enable */
ae00d812
LB
1128 } else if (*osi_additional_string == '\0') {
1129 strncpy(osi_additional_string, str, OSI_STRING_LENGTH_MAX);
1130 printk(KERN_INFO PREFIX "Added _OSI(%s)\n", str);
1da177e4
LT
1131 }
1132
1133 return 1;
1134}
1135
1136__setup("acpi_osi=", acpi_osi_setup);
1137
1138/* enable serialization to combat AE_ALREADY_EXISTS errors */
4be44fcd 1139static int __init acpi_serialize_setup(char *str)
1da177e4
LT
1140{
1141 printk(KERN_INFO PREFIX "serialize enabled\n");
1142
1143 acpi_gbl_all_methods_serialized = TRUE;
1144
1145 return 1;
1146}
1147
1148__setup("acpi_serialize", acpi_serialize_setup);
1149
1150/*
1151 * Wake and Run-Time GPES are expected to be separate.
1152 * We disable wake-GPEs at run-time to prevent spurious
1153 * interrupts.
1154 *
1155 * However, if a system exists that shares Wake and
1156 * Run-time events on the same GPE this flag is available
1157 * to tell Linux to keep the wake-time GPEs enabled at run-time.
1158 */
4be44fcd 1159static int __init acpi_wake_gpes_always_on_setup(char *str)
1da177e4
LT
1160{
1161 printk(KERN_INFO PREFIX "wake GPEs not disabled\n");
1162
1163 acpi_gbl_leave_wake_gpes_disabled = FALSE;
1164
1165 return 1;
1166}
1167
1168__setup("acpi_wake_gpes_always_on", acpi_wake_gpes_always_on_setup);
1169
73459f73
RM
1170/*
1171 * Acquire a spinlock.
1172 *
1173 * handle is a pointer to the spinlock_t.
73459f73
RM
1174 */
1175
967440e3 1176acpi_cpu_flags acpi_os_acquire_lock(acpi_spinlock lockp)
73459f73 1177{
b8e4d893 1178 acpi_cpu_flags flags;
967440e3 1179 spin_lock_irqsave(lockp, flags);
73459f73
RM
1180 return flags;
1181}
1182
1183/*
1184 * Release a spinlock. See above.
1185 */
1186
967440e3 1187void acpi_os_release_lock(acpi_spinlock lockp, acpi_cpu_flags flags)
73459f73 1188{
967440e3 1189 spin_unlock_irqrestore(lockp, flags);
73459f73
RM
1190}
1191
73459f73
RM
1192#ifndef ACPI_USE_LOCAL_CACHE
1193
1194/*******************************************************************************
1195 *
1196 * FUNCTION: acpi_os_create_cache
1197 *
b229cf92
BM
1198 * PARAMETERS: name - Ascii name for the cache
1199 * size - Size of each cached object
1200 * depth - Maximum depth of the cache (in objects) <ignored>
1201 * cache - Where the new cache object is returned
73459f73 1202 *
b229cf92 1203 * RETURN: status
73459f73
RM
1204 *
1205 * DESCRIPTION: Create a cache object
1206 *
1207 ******************************************************************************/
1208
1209acpi_status
4be44fcd 1210acpi_os_create_cache(char *name, u16 size, u16 depth, acpi_cache_t ** cache)
73459f73 1211{
20c2df83 1212 *cache = kmem_cache_create(name, size, 0, 0, NULL);
a6fdbf90 1213 if (*cache == NULL)
b229cf92
BM
1214 return AE_ERROR;
1215 else
1216 return AE_OK;
73459f73
RM
1217}
1218
1219/*******************************************************************************
1220 *
1221 * FUNCTION: acpi_os_purge_cache
1222 *
1223 * PARAMETERS: Cache - Handle to cache object
1224 *
1225 * RETURN: Status
1226 *
1227 * DESCRIPTION: Free all objects within the requested cache.
1228 *
1229 ******************************************************************************/
1230
4be44fcd 1231acpi_status acpi_os_purge_cache(acpi_cache_t * cache)
73459f73 1232{
50dd0969 1233 kmem_cache_shrink(cache);
4be44fcd 1234 return (AE_OK);
73459f73
RM
1235}
1236
1237/*******************************************************************************
1238 *
1239 * FUNCTION: acpi_os_delete_cache
1240 *
1241 * PARAMETERS: Cache - Handle to cache object
1242 *
1243 * RETURN: Status
1244 *
1245 * DESCRIPTION: Free all objects within the requested cache and delete the
1246 * cache object.
1247 *
1248 ******************************************************************************/
1249
4be44fcd 1250acpi_status acpi_os_delete_cache(acpi_cache_t * cache)
73459f73 1251{
1a1d92c1 1252 kmem_cache_destroy(cache);
4be44fcd 1253 return (AE_OK);
73459f73
RM
1254}
1255
1256/*******************************************************************************
1257 *
1258 * FUNCTION: acpi_os_release_object
1259 *
1260 * PARAMETERS: Cache - Handle to cache object
1261 * Object - The object to be released
1262 *
1263 * RETURN: None
1264 *
1265 * DESCRIPTION: Release an object to the specified cache. If cache is full,
1266 * the object is deleted.
1267 *
1268 ******************************************************************************/
1269
4be44fcd 1270acpi_status acpi_os_release_object(acpi_cache_t * cache, void *object)
73459f73 1271{
4be44fcd
LB
1272 kmem_cache_free(cache, object);
1273 return (AE_OK);
73459f73
RM
1274}
1275
5a4e1432
LB
1276/**
1277 * acpi_dmi_dump - dump DMI slots needed for blacklist entry
1278 *
1279 * Returns 0 on success
1280 */
1281int acpi_dmi_dump(void)
1282{
1283
1284 if (!dmi_available)
1285 return -1;
1286
1287 printk(KERN_NOTICE PREFIX "DMI System Vendor: %s\n",
1288 dmi_get_slot(DMI_SYS_VENDOR));
1289 printk(KERN_NOTICE PREFIX "DMI Product Name: %s\n",
1290 dmi_get_slot(DMI_PRODUCT_NAME));
1291 printk(KERN_NOTICE PREFIX "DMI Product Version: %s\n",
1292 dmi_get_slot(DMI_PRODUCT_VERSION));
1293 printk(KERN_NOTICE PREFIX "DMI Board Name: %s\n",
1294 dmi_get_slot(DMI_BOARD_NAME));
1295 printk(KERN_NOTICE PREFIX "DMI BIOS Vendor: %s\n",
1296 dmi_get_slot(DMI_BIOS_VENDOR));
1297 printk(KERN_NOTICE PREFIX "DMI BIOS Date: %s\n",
1298 dmi_get_slot(DMI_BIOS_DATE));
1299
1300 return 0;
1301}
1302
1303
b229cf92
BM
1304/******************************************************************************
1305 *
1306 * FUNCTION: acpi_os_validate_interface
1307 *
1308 * PARAMETERS: interface - Requested interface to be validated
1309 *
1310 * RETURN: AE_OK if interface is supported, AE_SUPPORT otherwise
1311 *
1312 * DESCRIPTION: Match an interface string to the interfaces supported by the
1313 * host. Strings originate from an AML call to the _OSI method.
1314 *
1315 *****************************************************************************/
1316
1317acpi_status
1318acpi_os_validate_interface (char *interface)
1319{
ae00d812
LB
1320 if (!strncmp(osi_additional_string, interface, OSI_STRING_LENGTH_MAX))
1321 return AE_OK;
f507654d 1322 if (!strcmp("Linux", interface)) {
d4b7dc49 1323
f40cd6fd 1324 printk(KERN_NOTICE PREFIX
d4b7dc49
LB
1325 "BIOS _OSI(Linux) query %s%s\n",
1326 osi_linux.enable ? "honored" : "ignored",
1327 osi_linux.cmdline ? " via cmdline" :
1328 osi_linux.dmi ? " via DMI" : "");
1329
1330 if (!osi_linux.dmi) {
1331 if (acpi_dmi_dump())
1332 printk(KERN_NOTICE PREFIX
1333 "[please extract dmidecode output]\n");
1334 printk(KERN_NOTICE PREFIX
1335 "Please send DMI info above to "
1336 "linux-acpi@vger.kernel.org\n");
1337 }
1338 if (!osi_linux.known && !osi_linux.cmdline) {
1339 printk(KERN_NOTICE PREFIX
1340 "If \"acpi_osi=%sLinux\" works better, "
1341 "please notify linux-acpi@vger.kernel.org\n",
1342 osi_linux.enable ? "!" : "");
1343 }
1344
1345 if (osi_linux.enable)
f507654d
LB
1346 return AE_OK;
1347 }
ae00d812 1348 return AE_SUPPORT;
b229cf92
BM
1349}
1350
b229cf92
BM
1351/******************************************************************************
1352 *
1353 * FUNCTION: acpi_os_validate_address
1354 *
1355 * PARAMETERS: space_id - ACPI space ID
1356 * address - Physical address
1357 * length - Address length
1358 *
1359 * RETURN: AE_OK if address/length is valid for the space_id. Otherwise,
1360 * should return AE_AML_ILLEGAL_ADDRESS.
1361 *
1362 * DESCRIPTION: Validate a system address via the host OS. Used to validate
1363 * the addresses accessed by AML operation regions.
1364 *
1365 *****************************************************************************/
1366
1367acpi_status
1368acpi_os_validate_address (
1369 u8 space_id,
1370 acpi_physical_address address,
1371 acpi_size length)
1372{
1373
1374 return AE_OK;
1375}
1376
73459f73 1377#endif