From patchwork Wed Jun 26 21:34:29 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yinghai Lu X-Patchwork-Id: 254875 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 3ED112C01D4 for ; Thu, 27 Jun 2013 07:35:13 +1000 (EST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753230Ab3FZVew (ORCPT ); Wed, 26 Jun 2013 17:34:52 -0400 Received: from aserp1040.oracle.com ([141.146.126.69]:18271 "EHLO aserp1040.oracle.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753104Ab3FZVeu (ORCPT ); Wed, 26 Jun 2013 17:34:50 -0400 Received: from acsinet22.oracle.com (acsinet22.oracle.com [141.146.126.238]) by aserp1040.oracle.com (Sentrion-MTA-4.3.1/Sentrion-MTA-4.3.1) with ESMTP id r5QLYcDh021400 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Wed, 26 Jun 2013 21:34:39 GMT Received: from userz7021.oracle.com (userz7021.oracle.com [156.151.31.85]) by acsinet22.oracle.com (8.14.4+Sun/8.14.4) with ESMTP id r5QLYbgR007388 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO); Wed, 26 Jun 2013 21:34:38 GMT Received: from abhmt116.oracle.com (abhmt116.oracle.com [141.146.116.68]) by userz7021.oracle.com (8.14.4+Sun/8.14.4) with ESMTP id r5QLYaZq011508; Wed, 26 Jun 2013 21:34:36 GMT Received: from linux-siqj.site (/10.132.126.191) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Wed, 26 Jun 2013 14:34:36 -0700 From: Yinghai Lu To: stable@vger.kernel.org, Greg Kroah-Hartman , Bjorn Helgaas , "Rafael J. Wysocki" , Jiang Liu Cc: Gavin Guo , linux-pci@vger.kernel.org, linux-acpi@vger.kernel.org, linux-kernel@vger.kernel.org, Yinghai Lu Subject: [PATCH v3.9 stable] PCI: acpiphp: Re-enumerate devices when host bridge receives Bus Check Date: Wed, 26 Jun 2013 14:34:29 -0700 Message-Id: <1372282469-7364-1-git-send-email-yinghai@kernel.org> X-Mailer: git-send-email 1.8.1.4 In-Reply-To: <20130605223852.GA16729@kroah.com> X-Source-IP: acsinet22.oracle.com [141.146.126.238] Sender: linux-pci-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pci@vger.kernel.org Backporting for v3.9 for 3f327e39b4 (PCI: acpiphp: Re-enumerate devices when host bridge receives Bus Check). When a PCI host bridge device receives a Bus Check notification, we must re-enumerate starting with the bridge to discover changes (devices that have been added or removed). Prior to 668192b678 ("PCI: acpiphp: Move host bridge hotplug to pci_root.c"), this happened in _handle_hotplug_event_bridge(). After that commit, _handle_hotplug_event_bridge() is not installed for host bridges, and the host bridge notify handler, _handle_hotplug_event_root() did not re-enumerate. This patch adds re-enumeration to _handle_hotplug_event_root(). This fixes cases where we don't notice the addition or removal of PCI devices, e.g., the PCI-to-USB ExpressCard in the bugzilla below. -v1: Backport of 3f327e39b4 to v3.9 by Bjorn Helgaas -v2: use request_module("acpiphp") for acpiphp as module instead of built-in. [bhelgaas: changelog, references] Reference: https://lkml.kernel.org/r/CAAh6nkmbKR3HTqm5ommevsBwhL_u0N8Rk7Wsms_LfP=nBgKNew@mail.gmail.com Reference: https://bugzilla.kernel.org/show_bug.cgi?id=57961 Reported-by: Gavin Guo Tested-by: Gavin Guo Signed-off-by: Yinghai Lu Signed-off-by: Bjorn Helgaas Acked-by: Rafael J. Wysocki --- drivers/acpi/pci_root.c | 7 ++++++- drivers/pci/hotplug/acpiphp_glue.c | 14 ++++++++++++++ include/linux/pci-acpi.h | 2 ++ 3 files changed, 22 insertions(+), 1 deletion(-) -- 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 Index: linux-3.9.4/drivers/acpi/pci_root.c =================================================================== --- linux-3.9.4.orig/drivers/acpi/pci_root.c +++ linux-3.9.4/drivers/acpi/pci_root.c @@ -665,6 +665,7 @@ static void handle_root_bridge_removal(s kfree(ej_event); } +void (*acpiphp_check_host_bridge)(acpi_handle handle); static void _handle_hotplug_event_root(struct work_struct *work) { struct acpi_pci_root *root; @@ -687,7 +688,11 @@ static void _handle_hotplug_event_root(s /* bus enumerate */ printk(KERN_DEBUG "%s: Bus check notify on %s\n", __func__, (char *)buffer.pointer); - if (!root) + if (root) { + request_module("acpiphp"); + if (acpiphp_check_host_bridge) + acpiphp_check_host_bridge(handle); + } else handle_root_bridge_insertion(handle); break; Index: linux-3.9.4/drivers/pci/hotplug/acpiphp_glue.c =================================================================== --- linux-3.9.4.orig/drivers/pci/hotplug/acpiphp_glue.c +++ linux-3.9.4/drivers/pci/hotplug/acpiphp_glue.c @@ -1122,6 +1122,18 @@ check_sub_bridges(acpi_handle handle, u3 return AE_OK ; } +static void __acpiphp_check_host_bridge(acpi_handle handle) +{ + struct acpiphp_bridge *bridge; + + bridge = acpiphp_handle_to_bridge(handle); + if (bridge) + acpiphp_check_bridge(bridge); + + acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, + ACPI_UINT32_MAX, check_sub_bridges, NULL, NULL, NULL); +} + static void _handle_hotplug_event_bridge(struct work_struct *work) { struct acpiphp_bridge *bridge; @@ -1305,6 +1317,7 @@ static struct acpi_pci_driver acpi_pci_h int __init acpiphp_glue_init(void) { acpi_pci_register_driver(&acpi_pci_hp_driver); + acpiphp_check_host_bridge = __acpiphp_check_host_bridge; return 0; } @@ -1317,6 +1330,7 @@ int __init acpiphp_glue_init(void) */ void acpiphp_glue_exit(void) { + acpiphp_check_host_bridge = NULL; acpi_pci_unregister_driver(&acpi_pci_hp_driver); } Index: linux-3.9.4/include/linux/pci-acpi.h =================================================================== --- linux-3.9.4.orig/include/linux/pci-acpi.h +++ linux-3.9.4/include/linux/pci-acpi.h @@ -43,6 +43,8 @@ static inline acpi_handle acpi_pci_get_b } #endif +extern void (*acpiphp_check_host_bridge)(acpi_handle handle); + #ifdef CONFIG_ACPI_APEI extern bool aer_acpi_firmware_first(void); #else