diff mbox

[1/4] ACPI: Support _OSI("Darwin") correctly

Message ID 1401640436-1947-2-git-send-email-matthew.garrett@nebula.com (mailing list archive)
State New, archived
Delegated to: Bjorn Helgaas
Headers show

Commit Message

Matthew Garrett June 1, 2014, 4:33 p.m. UTC
Apple hardware queries _OSI("Darwin") in order to determine whether the
system is running OS X, and changes firmware behaviour based on the answer.
The most obvious difference in behaviour is that Thunderbolt hardware is
forcibly powered down unless the system is running OS X. The obvious solution
would be to simply add Darwin to the list of supported _OSI strings, but this
causes problems.

Recent Apple hardware includes two separate methods for checking _OSI
strings. The first will check whether Darwin is supported, and if so will
exit. The second will check whether Darwin is supported, but will then
continue to check for further operating systems. If a further operating
system is found then later firmware code will assume that the OS is not OS X.
This results in the unfortunate situation where the Thunderbolt controller is
available at boot time but remains powered down after suspend.

The easiest way to handle this is to special-case it in the Linux-specific
OSI handling code. If we see Darwin, we should answer true and then disable
all other _OSI vendor strings.

Signed-off-by: Matthew Garrett <matthew.garrett@nebula.com>
---
 drivers/acpi/acpica/utosi.c |  1 +
 drivers/acpi/osl.c          | 10 ++++++++++
 include/acpi/actypes.h      | 25 +++++++++++++------------
 3 files changed, 24 insertions(+), 12 deletions(-)

Comments

Rafael J. Wysocki June 17, 2014, 12:11 p.m. UTC | #1
On Sunday, June 01, 2014 12:33:53 PM Matthew Garrett wrote:
> Apple hardware queries _OSI("Darwin") in order to determine whether the
> system is running OS X, and changes firmware behaviour based on the answer.
> The most obvious difference in behaviour is that Thunderbolt hardware is
> forcibly powered down unless the system is running OS X. The obvious solution
> would be to simply add Darwin to the list of supported _OSI strings, but this
> causes problems.
> 
> Recent Apple hardware includes two separate methods for checking _OSI
> strings. The first will check whether Darwin is supported, and if so will
> exit. The second will check whether Darwin is supported, but will then
> continue to check for further operating systems. If a further operating
> system is found then later firmware code will assume that the OS is not OS X.
> This results in the unfortunate situation where the Thunderbolt controller is
> available at boot time but remains powered down after suspend.
> 
> The easiest way to handle this is to special-case it in the Linux-specific
> OSI handling code. If we see Darwin, we should answer true and then disable
> all other _OSI vendor strings.
> 
> Signed-off-by: Matthew Garrett <matthew.garrett@nebula.com>

Does applying this patch without the rest of the series makes things worse
or better on the machines in question (or perhaps it doesn't matter at all
alone)?

Rafael


> ---
>  drivers/acpi/acpica/utosi.c |  1 +
>  drivers/acpi/osl.c          | 10 ++++++++++
>  include/acpi/actypes.h      | 25 +++++++++++++------------
>  3 files changed, 24 insertions(+), 12 deletions(-)
> 
> diff --git a/drivers/acpi/acpica/utosi.c b/drivers/acpi/acpica/utosi.c
> index 685766f..63b0a3b 100644
> --- a/drivers/acpi/acpica/utosi.c
> +++ b/drivers/acpi/acpica/utosi.c
> @@ -87,6 +87,7 @@ ACPI_MODULE_NAME("utosi")
>  static struct acpi_interface_info acpi_default_supported_interfaces[] = {
>  	/* Operating System Vendor Strings */
>  
> +	{"Darwin", NULL, 0, ACPI_OSI_DARWIN},	/* OS X */
>  	{"Windows 2000", NULL, 0, ACPI_OSI_WIN_2000},	/* Windows 2000 */
>  	{"Windows 2001", NULL, 0, ACPI_OSI_WIN_XP},	/* Windows XP */
>  	{"Windows 2001 SP1", NULL, 0, ACPI_OSI_WIN_XP_SP1},	/* Windows XP SP1 */
> diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c
> index 6776c59..312ab5c 100644
> --- a/drivers/acpi/osl.c
> +++ b/drivers/acpi/osl.c
> @@ -152,6 +152,16 @@ static u32 acpi_osi_handler(acpi_string interface, u32 supported)
>  			osi_linux.dmi ? " via DMI" : "");
>  	}
>  
> +	if (!strcmp("Darwin", interface)) {
> +		/*
> +		 * Apple firmware will behave poorly if it receives positive
> +		 * answers to "Darwin" and any other OS. Respond positively
> +		 * to Darwin and then disable all other vendor strings.
> +		 */
> +		acpi_update_interfaces(ACPI_DISABLE_ALL_VENDOR_STRINGS);
> +		supported = ACPI_UINT32_MAX;
> +	}
> +
>  	return supported;
>  }
>  
> diff --git a/include/acpi/actypes.h b/include/acpi/actypes.h
> index e763565..1c2ef56 100644
> --- a/include/acpi/actypes.h
> +++ b/include/acpi/actypes.h
> @@ -1210,17 +1210,18 @@ struct acpi_memory_list {
>  #define ACPI_ENABLE_ALL_FEATURE_STRINGS     (ACPI_ENABLE_INTERFACES | ACPI_FEATURE_STRINGS)
>  #define ACPI_ENABLE_ALL_STRINGS             (ACPI_ENABLE_INTERFACES | ACPI_VENDOR_STRINGS | ACPI_FEATURE_STRINGS)
>  
> -#define ACPI_OSI_WIN_2000               0x01
> -#define ACPI_OSI_WIN_XP                 0x02
> -#define ACPI_OSI_WIN_XP_SP1             0x03
> -#define ACPI_OSI_WINSRV_2003            0x04
> -#define ACPI_OSI_WIN_XP_SP2             0x05
> -#define ACPI_OSI_WINSRV_2003_SP1        0x06
> -#define ACPI_OSI_WIN_VISTA              0x07
> -#define ACPI_OSI_WINSRV_2008            0x08
> -#define ACPI_OSI_WIN_VISTA_SP1          0x09
> -#define ACPI_OSI_WIN_VISTA_SP2          0x0A
> -#define ACPI_OSI_WIN_7                  0x0B
> -#define ACPI_OSI_WIN_8                  0x0C
> +#define ACPI_OSI_DARWIN                 0x01
> +#define ACPI_OSI_WIN_2000               0x02
> +#define ACPI_OSI_WIN_XP                 0x03
> +#define ACPI_OSI_WIN_XP_SP1             0x04
> +#define ACPI_OSI_WINSRV_2003            0x05
> +#define ACPI_OSI_WIN_XP_SP2             0x06
> +#define ACPI_OSI_WINSRV_2003_SP1        0x07
> +#define ACPI_OSI_WIN_VISTA              0x08
> +#define ACPI_OSI_WINSRV_2008            0x09
> +#define ACPI_OSI_WIN_VISTA_SP1          0x0A
> +#define ACPI_OSI_WIN_VISTA_SP2          0x0B
> +#define ACPI_OSI_WIN_7                  0x0C
> +#define ACPI_OSI_WIN_8                  0x0D
>  
>  #endif				/* __ACTYPES_H__ */
>
Matthew Garrett June 17, 2014, 2:46 p.m. UTC | #2
On Tue, Jun 17, 2014 at 02:11:36PM +0200, Rafael J. Wysocki wrote:
> On Sunday, June 01, 2014 12:33:53 PM Matthew Garrett wrote:
> > Apple hardware queries _OSI("Darwin") in order to determine whether the
> > system is running OS X, and changes firmware behaviour based on the answer.
> > The most obvious difference in behaviour is that Thunderbolt hardware is
> > forcibly powered down unless the system is running OS X. The obvious solution
> > would be to simply add Darwin to the list of supported _OSI strings, but this
> > causes problems.
> > 
> > Recent Apple hardware includes two separate methods for checking _OSI
> > strings. The first will check whether Darwin is supported, and if so will
> > exit. The second will check whether Darwin is supported, but will then
> > continue to check for further operating systems. If a further operating
> > system is found then later firmware code will assume that the OS is not OS X.
> > This results in the unfortunate situation where the Thunderbolt controller is
> > available at boot time but remains powered down after suspend.
> > 
> > The easiest way to handle this is to special-case it in the Linux-specific
> > OSI handling code. If we see Darwin, we should answer true and then disable
> > all other _OSI vendor strings.
> > 
> > Signed-off-by: Matthew Garrett <matthew.garrett@nebula.com>
> 
> Does applying this patch without the rest of the series makes things worse
> or better on the machines in question (or perhaps it doesn't matter at all
> alone)?

On its own, I think this will do nothing.
Matthew Garrett June 18, 2014, 5:26 a.m. UTC | #3
On Tue, Jun 17, 2014 at 03:46:15PM +0100, Matthew Garrett wrote:
> On Tue, Jun 17, 2014 at 02:11:36PM +0200, Rafael J. Wysocki wrote:
> > Does applying this patch without the rest of the series makes things worse
> > or better on the machines in question (or perhaps it doesn't matter at all
> > alone)?
> 
> On its own, I think this will do nothing.

Ugh, no, sorry - on its own, this will break PCIe hotplug events and 
battery reporting. It should only be merged with the others.
Rafael J. Wysocki June 18, 2014, 11:42 p.m. UTC | #4
On Wednesday, June 18, 2014 06:26:15 AM Matthew Garrett wrote:
> On Tue, Jun 17, 2014 at 03:46:15PM +0100, Matthew Garrett wrote:
> > On Tue, Jun 17, 2014 at 02:11:36PM +0200, Rafael J. Wysocki wrote:
> > > Does applying this patch without the rest of the series makes things worse
> > > or better on the machines in question (or perhaps it doesn't matter at all
> > > alone)?
> > 
> > On its own, I think this will do nothing.
> 
> Ugh, no, sorry - on its own, this will break PCIe hotplug events and 
> battery reporting. It should only be merged with the others.

Well, in that case it is not useful to split that material into
multiple patches.  And it will need to be Linux-specific, as adding
patch [1/4] to upstream ACPICA might break some other OSes using it.

Rafael

--
To unsubscribe from this list: send the line "unsubscribe linux-pci" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
diff mbox

Patch

diff --git a/drivers/acpi/acpica/utosi.c b/drivers/acpi/acpica/utosi.c
index 685766f..63b0a3b 100644
--- a/drivers/acpi/acpica/utosi.c
+++ b/drivers/acpi/acpica/utosi.c
@@ -87,6 +87,7 @@  ACPI_MODULE_NAME("utosi")
 static struct acpi_interface_info acpi_default_supported_interfaces[] = {
 	/* Operating System Vendor Strings */
 
+	{"Darwin", NULL, 0, ACPI_OSI_DARWIN},	/* OS X */
 	{"Windows 2000", NULL, 0, ACPI_OSI_WIN_2000},	/* Windows 2000 */
 	{"Windows 2001", NULL, 0, ACPI_OSI_WIN_XP},	/* Windows XP */
 	{"Windows 2001 SP1", NULL, 0, ACPI_OSI_WIN_XP_SP1},	/* Windows XP SP1 */
diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c
index 6776c59..312ab5c 100644
--- a/drivers/acpi/osl.c
+++ b/drivers/acpi/osl.c
@@ -152,6 +152,16 @@  static u32 acpi_osi_handler(acpi_string interface, u32 supported)
 			osi_linux.dmi ? " via DMI" : "");
 	}
 
+	if (!strcmp("Darwin", interface)) {
+		/*
+		 * Apple firmware will behave poorly if it receives positive
+		 * answers to "Darwin" and any other OS. Respond positively
+		 * to Darwin and then disable all other vendor strings.
+		 */
+		acpi_update_interfaces(ACPI_DISABLE_ALL_VENDOR_STRINGS);
+		supported = ACPI_UINT32_MAX;
+	}
+
 	return supported;
 }
 
diff --git a/include/acpi/actypes.h b/include/acpi/actypes.h
index e763565..1c2ef56 100644
--- a/include/acpi/actypes.h
+++ b/include/acpi/actypes.h
@@ -1210,17 +1210,18 @@  struct acpi_memory_list {
 #define ACPI_ENABLE_ALL_FEATURE_STRINGS     (ACPI_ENABLE_INTERFACES | ACPI_FEATURE_STRINGS)
 #define ACPI_ENABLE_ALL_STRINGS             (ACPI_ENABLE_INTERFACES | ACPI_VENDOR_STRINGS | ACPI_FEATURE_STRINGS)
 
-#define ACPI_OSI_WIN_2000               0x01
-#define ACPI_OSI_WIN_XP                 0x02
-#define ACPI_OSI_WIN_XP_SP1             0x03
-#define ACPI_OSI_WINSRV_2003            0x04
-#define ACPI_OSI_WIN_XP_SP2             0x05
-#define ACPI_OSI_WINSRV_2003_SP1        0x06
-#define ACPI_OSI_WIN_VISTA              0x07
-#define ACPI_OSI_WINSRV_2008            0x08
-#define ACPI_OSI_WIN_VISTA_SP1          0x09
-#define ACPI_OSI_WIN_VISTA_SP2          0x0A
-#define ACPI_OSI_WIN_7                  0x0B
-#define ACPI_OSI_WIN_8                  0x0C
+#define ACPI_OSI_DARWIN                 0x01
+#define ACPI_OSI_WIN_2000               0x02
+#define ACPI_OSI_WIN_XP                 0x03
+#define ACPI_OSI_WIN_XP_SP1             0x04
+#define ACPI_OSI_WINSRV_2003            0x05
+#define ACPI_OSI_WIN_XP_SP2             0x06
+#define ACPI_OSI_WINSRV_2003_SP1        0x07
+#define ACPI_OSI_WIN_VISTA              0x08
+#define ACPI_OSI_WINSRV_2008            0x09
+#define ACPI_OSI_WIN_VISTA_SP1          0x0A
+#define ACPI_OSI_WIN_VISTA_SP2          0x0B
+#define ACPI_OSI_WIN_7                  0x0C
+#define ACPI_OSI_WIN_8                  0x0D
 
 #endif				/* __ACTYPES_H__ */