Re: [PATCH 5/6] ACPI: Add support for native USB4 control _OSC

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Tue, Jan 26, 2021 at 5:01 PM Mika Westerberg
<mika.westerberg@xxxxxxxxxxxxxxx> wrote:
>
> ACPI 6.4 introduced a new _OSC capability that is used negotiate native
> connection manager support. Connection manager is the entity that is
> responsible for tunneling over the USB4 fabric. If the platform rejects
> the native access then firmware based connection manager is used.
>
> The new _OSC also includes a set of bits that can be used to disable
> certain tunnel types such as PCIe for security reasons for instance.
>
> This implements the new USB4 _OSC so that we try to negotiate native
> USB4 support if the Thunderbolt/USB4 (CONFIG_USB4) driver is enabled.
> Drivers can determine what was negotiated by checking two new variables
> exposed in this patch.
>
> Cc: Rafael J. Wysocki <rafael.j.wysocki@xxxxxxxxx>
> Signed-off-by: Mika Westerberg <mika.westerberg@xxxxxxxxxxxxxxx>

Reviewed-by: Rafael J. Wysocki <rafael.j.wysocki@xxxxxxxxx>

> ---
>  drivers/acpi/bus.c   | 76 ++++++++++++++++++++++++++++++++++++++++++++
>  include/linux/acpi.h | 10 ++++++
>  2 files changed, 86 insertions(+)
>
> diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c
> index ca7c7b2bf56e..f7ad2d283e51 100644
> --- a/drivers/acpi/bus.c
> +++ b/drivers/acpi/bus.c
> @@ -281,6 +281,12 @@ bool osc_sb_apei_support_acked;
>  bool osc_pc_lpi_support_confirmed;
>  EXPORT_SYMBOL_GPL(osc_pc_lpi_support_confirmed);
>
> +/*
> + * ACPI 6.4 Operating System Capabilities for USB.
> + */
> +bool osc_sb_native_usb4_support_confirmed;
> +EXPORT_SYMBOL_GPL(osc_sb_native_usb4_support_confirmed);
> +
>  static u8 sb_uuid_str[] = "0811B06E-4A27-44F9-8D60-3CBBC22E7B48";
>  static void acpi_bus_osc_negotiate_platform_control(void)
>  {
> @@ -317,6 +323,9 @@ static void acpi_bus_osc_negotiate_platform_control(void)
>         if (IS_ENABLED(CONFIG_SCHED_MC_PRIO))
>                 capbuf[OSC_SUPPORT_DWORD] |= OSC_SB_CPC_DIVERSE_HIGH_SUPPORT;
>
> +       if (IS_ENABLED(CONFIG_USB4))
> +               capbuf[OSC_SUPPORT_DWORD] |= OSC_SB_NATIVE_USB4_SUPPORT;
> +
>         if (!ghes_disable)
>                 capbuf[OSC_SUPPORT_DWORD] |= OSC_SB_APEI_SUPPORT;
>         if (ACPI_FAILURE(acpi_get_handle(NULL, "\\_SB", &handle)))
> @@ -348,8 +357,74 @@ static void acpi_bus_osc_negotiate_platform_control(void)
>                         capbuf_ret[OSC_SUPPORT_DWORD] & OSC_SB_APEI_SUPPORT;
>                 osc_pc_lpi_support_confirmed =
>                         capbuf_ret[OSC_SUPPORT_DWORD] & OSC_SB_PCLPI_SUPPORT;
> +               osc_sb_native_usb4_support_confirmed =
> +                       capbuf_ret[OSC_SUPPORT_DWORD] & OSC_SB_NATIVE_USB4_SUPPORT;
> +       }
> +
> +       kfree(context.ret.pointer);
> +}
> +
> +/*
> + * Native control of USB4 capabilities. If any of the tunneling bits is
> + * set it means OS is in control and we use software based connection
> + * manager.
> + */
> +u32 osc_sb_native_usb4_control;
> +EXPORT_SYMBOL_GPL(osc_sb_native_usb4_control);
> +
> +static void acpi_bus_decode_usb_osc(const char *msg, u32 bits)
> +{
> +       printk(KERN_INFO PREFIX "%s USB3%c DisplayPort%c PCIe%c XDomain%c\n", msg,
> +              (bits & OSC_USB_USB3_TUNNELING) ? '+' : '-',
> +              (bits & OSC_USB_DP_TUNNELING) ? '+' : '-',
> +              (bits & OSC_USB_PCIE_TUNNELING) ? '+' : '-',
> +              (bits & OSC_USB_XDOMAIN) ? '+' : '-');
> +}
> +
> +static u8 sb_usb_uuid_str[] = "23A0D13A-26AB-486C-9C5F-0FFA525A575A";
> +static void acpi_bus_osc_negotiate_usb_control(void)
> +{
> +       u32 capbuf[3];
> +       struct acpi_osc_context context = {
> +               .uuid_str = sb_usb_uuid_str,
> +               .rev = 1,
> +               .cap.length = sizeof(capbuf),
> +               .cap.pointer = capbuf,
> +       };
> +       acpi_handle handle;
> +       acpi_status status;
> +       u32 control;
> +
> +       if (!osc_sb_native_usb4_support_confirmed)
> +               return;
> +
> +       if (ACPI_FAILURE(acpi_get_handle(NULL, "\\_SB", &handle)))
> +               return;
> +
> +       control = OSC_USB_USB3_TUNNELING | OSC_USB_DP_TUNNELING |
> +                 OSC_USB_PCIE_TUNNELING | OSC_USB_XDOMAIN;
> +
> +       capbuf[OSC_QUERY_DWORD] = 0;
> +       capbuf[OSC_SUPPORT_DWORD] = 0;
> +       capbuf[OSC_CONTROL_DWORD] = control;
> +
> +       status = acpi_run_osc(handle, &context);
> +       if (ACPI_FAILURE(status))
> +               return;
> +
> +       if (context.ret.length != sizeof(capbuf)) {
> +               printk(KERN_INFO PREFIX "USB4 _OSC: returned invalid length buffer\n");
> +               goto out_free;
>         }
>
> +       osc_sb_native_usb4_control =
> +               control & ((u32 *)context.ret.pointer)[OSC_CONTROL_DWORD];
> +
> +       acpi_bus_decode_usb_osc("USB4 _OSC: OS supports", control);
> +       acpi_bus_decode_usb_osc("USB4 _OSC: OS controls",
> +                               osc_sb_native_usb4_control);
> +
> +out_free:
>         kfree(context.ret.pointer);
>  }
>
> @@ -1188,6 +1263,7 @@ static int __init acpi_bus_init(void)
>          * so it must be run after ACPI_FULL_INITIALIZATION
>          */
>         acpi_bus_osc_negotiate_platform_control();
> +       acpi_bus_osc_negotiate_usb_control();
>
>         /*
>          * _PDC control method may load dynamic SSDT tables,
> diff --git a/include/linux/acpi.h b/include/linux/acpi.h
> index 2630c2e953f7..ac68c2d4e393 100644
> --- a/include/linux/acpi.h
> +++ b/include/linux/acpi.h
> @@ -546,9 +546,19 @@ acpi_status acpi_run_osc(acpi_handle handle, struct acpi_osc_context *context);
>  #define OSC_SB_OSLPI_SUPPORT                   0x00000100
>  #define OSC_SB_CPC_DIVERSE_HIGH_SUPPORT                0x00001000
>  #define OSC_SB_GENERIC_INITIATOR_SUPPORT       0x00002000
> +#define OSC_SB_NATIVE_USB4_SUPPORT             0x00040000
>
>  extern bool osc_sb_apei_support_acked;
>  extern bool osc_pc_lpi_support_confirmed;
> +extern bool osc_sb_native_usb4_support_confirmed;
> +
> +/* USB4 Capabilities */
> +#define OSC_USB_USB3_TUNNELING                 0x00000001
> +#define OSC_USB_DP_TUNNELING                   0x00000002
> +#define OSC_USB_PCIE_TUNNELING                 0x00000004
> +#define OSC_USB_XDOMAIN                                0x00000008
> +
> +extern u32 osc_sb_native_usb4_control;
>
>  /* PCI Host Bridge _OSC: Capabilities DWORD 2: Support Field */
>  #define OSC_PCI_EXT_CONFIG_SUPPORT             0x00000001
> --
> 2.29.2
>



[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux