From patchwork Mon Feb 12 10:55:23 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mika Westerberg X-Patchwork-Id: 10212199 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 0D42260329 for ; Mon, 12 Feb 2018 10:55:30 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 0E3ED28BBA for ; Mon, 12 Feb 2018 10:55:30 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 01F9828C01; Mon, 12 Feb 2018 10:55:29 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.9 required=2.0 tests=BAYES_00,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 607AC28BBA for ; Mon, 12 Feb 2018 10:55:29 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S933863AbeBLKz2 (ORCPT ); Mon, 12 Feb 2018 05:55:28 -0500 Received: from mga12.intel.com ([192.55.52.136]:35315 "EHLO mga12.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S933760AbeBLKz1 (ORCPT ); Mon, 12 Feb 2018 05:55:27 -0500 X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga001.fm.intel.com ([10.253.24.23]) by fmsmga106.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 12 Feb 2018 02:55:27 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.46,501,1511856000"; d="scan'208";a="30075836" Received: from black.fi.intel.com ([10.237.72.28]) by fmsmga001.fm.intel.com with ESMTP; 12 Feb 2018 02:55:25 -0800 Received: by black.fi.intel.com (Postfix, from userid 1001) id 20DEBEC; Mon, 12 Feb 2018 12:55:24 +0200 (EET) From: Mika Westerberg To: "Rafael J. Wysocki" , Bjorn Helgaas Cc: Len Brown , Mike Lothian , Greg Kroah-Hartman , Mika Westerberg , linux-acpi@vger.kernel.org, linux-pci@vger.kernel.org Subject: [PATCH] ACPI / hotplug / PCI: Check presence of slot itself in get_slot_status() Date: Mon, 12 Feb 2018 13:55:23 +0300 Message-Id: <20180212105523.15984-1-mika.westerberg@linux.intel.com> X-Mailer: git-send-email 2.15.1 Sender: linux-acpi-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-acpi@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Mike Lothian reported that plugging in a USB-C device does not work properly in his Dell Alienware system. This system has Intel Alpine Ridge Thunderbolt controller providing USB-C functionality. In these systems the USB controller (xHCI) is hotplugged whenever a device is connected to the port using ACPI based hotplug. The ACPI description of the root port in question looks as follows: Device (RP01) { Name (_ADR, 0x001C0000) Device (PXSX) { Name (_ADR, 0x02) Method (_RMV, 0, NotSerialized) { // ... } } Here _ADR 0x02 means device 0, function 2 on the bus under root port (RP1) but that seems to be incorrect because device 0 is the upstream port of the Alpine Ridge PCIe switch and it does not have other functions than 0 (the bridge itself). When we get ACPI Notify() to the root port resulting from connecting a USB-C device, Linux tries to read PCI_VENDOR_ID from device 0, function 2 which of course always returns 0xffffffff because there is no such function and we never find the device. In Windows this works fine. Now, since we get ACPI Notify() to the root port and not to the PXSX device we should actually start our scan from there as well and not from the non-existent PXSX device so fix this by checking presence of the slot itself (function 0) if we fail to do that otherwise. While there use pci_bus_read_dev_vendor_id() in get_slot_status() which is the recommended way to read device and vendor ID of device on PCI bus. Link: https://bugzilla.kernel.org/show_bug.cgi?id=198557 Reported-by: Mike Lothian Signed-off-by: Mika Westerberg Cc: Greg Kroah-Hartman Cc: stable@vger.kernel.org Tested-by: Mike Lothian Reviewed-by: Rafael J. Wysocki --- drivers/pci/hotplug/acpiphp_glue.c | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/drivers/pci/hotplug/acpiphp_glue.c b/drivers/pci/hotplug/acpiphp_glue.c index e2198a2feeca..b45b375c0e6c 100644 --- a/drivers/pci/hotplug/acpiphp_glue.c +++ b/drivers/pci/hotplug/acpiphp_glue.c @@ -541,6 +541,7 @@ static unsigned int get_slot_status(struct acpiphp_slot *slot) { unsigned long long sta = 0; struct acpiphp_func *func; + u32 dvid; list_for_each_entry(func, &slot->funcs, sibling) { if (func->flags & FUNC_HAS_STA) { @@ -551,19 +552,27 @@ static unsigned int get_slot_status(struct acpiphp_slot *slot) if (ACPI_SUCCESS(status) && sta) break; } else { - u32 dvid; - - pci_bus_read_config_dword(slot->bus, - PCI_DEVFN(slot->device, - func->function), - PCI_VENDOR_ID, &dvid); - if (dvid != 0xffffffff) { + if (pci_bus_read_dev_vendor_id(slot->bus, + PCI_DEVFN(slot->device, func->function), + &dvid, 0)) { sta = ACPI_STA_ALL; break; } } } + if (!sta) { + /* + * Check for the slot itself since it may be that the + * ACPI slot is a device below PCIe upstream port so in + * that case it may not even be reachable yet. + */ + if (pci_bus_read_dev_vendor_id(slot->bus, + PCI_DEVFN(slot->device, 0), &dvid, 0)) { + sta = ACPI_STA_ALL; + } + } + return (unsigned int)sta; }