// SPDX-License-Identifier: GPL-2.0-or-later /* * osi.c - _OSI implementation * * Copyright (C) 2016 Intel Corporation * Author: Lv Zheng <[email protected]> */ /* Uncomment next line to get verbose printout */ /* #define DEBUG */ #define pr_fmt(fmt) … #include <linux/module.h> #include <linux/kernel.h> #include <linux/acpi.h> #include <linux/dmi.h> #include <linux/platform_data/x86/apple.h> #include "internal.h" #define OSI_STRING_LENGTH_MAX … #define OSI_STRING_ENTRIES_MAX … struct acpi_osi_entry { … }; static struct acpi_osi_config { … } osi_config; static struct acpi_osi_config osi_config; static struct acpi_osi_entry osi_setup_entries[OSI_STRING_ENTRIES_MAX] __initdata = …; static u32 acpi_osi_handler(acpi_string interface, u32 supported) { … } void __init acpi_osi_setup(char *str) { … } static void __init __acpi_osi_setup_darwin(bool enable) { … } static void __init acpi_osi_setup_darwin(bool enable) { … } /* * The story of _OSI(Linux) * * From pre-history through Linux-2.6.22, Linux responded TRUE upon a BIOS * OSI(Linux) query. * * Unfortunately, reference BIOS writers got wind of this and put * OSI(Linux) in their example code, quickly exposing this string as * ill-conceived and opening the door to an un-bounded number of BIOS * incompatibilities. * * For example, OSI(Linux) was used on resume to re-POST a video card on * one system, because Linux at that time could not do a speedy restore in * its native driver. But then upon gaining quick native restore * capability, Linux has no way to tell the BIOS to skip the time-consuming * POST -- putting Linux at a permanent performance disadvantage. On * another system, the BIOS writer used OSI(Linux) to infer native OS * support for IPMI! On other systems, OSI(Linux) simply got in the way of * Linux claiming to be compatible with other operating systems, exposing * BIOS issues such as skipped device initialization. * * So "Linux" turned out to be a really poor chose of OSI string, and from * Linux-2.6.23 onward we respond FALSE. * * BIOS writers should NOT query _OSI(Linux) on future systems. Linux will * complain on the console when it sees it, and return FALSE. To get Linux * to return TRUE for your system will require a kernel source update to * add a DMI entry, or boot with "acpi_osi=Linux" */ static void __init __acpi_osi_setup_linux(bool enable) { … } static void __init acpi_osi_setup_linux(bool enable) { … } /* * Modify the list of "OS Interfaces" reported to BIOS via _OSI * * empty string disables _OSI * string starting with '!' disables that string * otherwise string is added to list, augmenting built-in strings */ static void __init acpi_osi_setup_late(void) { … } static int __init osi_setup(char *str) { … } __setup(…); bool acpi_osi_is_win8(void) { … } EXPORT_SYMBOL(…); static void __init acpi_osi_dmi_darwin(void) { … } static void __init acpi_osi_dmi_linux(bool enable, const struct dmi_system_id *d) { … } static int __init dmi_enable_osi_linux(const struct dmi_system_id *d) { … } static int __init dmi_disable_osi_vista(const struct dmi_system_id *d) { … } static int __init dmi_disable_osi_win7(const struct dmi_system_id *d) { … } static int __init dmi_disable_osi_win8(const struct dmi_system_id *d) { … } /* * Linux default _OSI response behavior is determined by this DMI table. * * Note that _OSI("Linux")/_OSI("Darwin") determined here can be overridden * by acpi_osi=!Linux/acpi_osi=!Darwin command line options. */ static const struct dmi_system_id acpi_osi_dmi_table[] __initconst = …; static __init void acpi_osi_dmi_blacklisted(void) { … } int __init early_acpi_osi_init(void) { … } int __init acpi_osi_init(void) { … }