From patchwork Thu Jun 6 01:55:53 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yinghai Lu X-Patchwork-Id: 249244 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 068B02C00B8 for ; Thu, 6 Jun 2013 11:56:07 +1000 (EST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1756518Ab3FFB4F (ORCPT ); Wed, 5 Jun 2013 21:56:05 -0400 Received: from userp1040.oracle.com ([156.151.31.81]:39648 "EHLO userp1040.oracle.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1755418Ab3FFB4E (ORCPT ); Wed, 5 Jun 2013 21:56:04 -0400 Received: from acsinet21.oracle.com (acsinet21.oracle.com [141.146.126.237]) by userp1040.oracle.com (Sentrion-MTA-4.3.1/Sentrion-MTA-4.3.1) with ESMTP id r561tk5w003175 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Thu, 6 Jun 2013 01:55:47 GMT Received: from userz7021.oracle.com (userz7021.oracle.com [156.151.31.85]) by acsinet21.oracle.com (8.14.4+Sun/8.14.4) with ESMTP id r561tlB9001980 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO); Thu, 6 Jun 2013 01:55:48 GMT Received: from abhmt105.oracle.com (abhmt105.oracle.com [141.146.116.57]) by userz7021.oracle.com (8.14.4+Sun/8.14.4) with ESMTP id r561tkQu025369; Thu, 6 Jun 2013 01:55:46 GMT Received: from linux-siqj.site (/75.36.252.179) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Wed, 05 Jun 2013 18:55:46 -0700 From: Yinghai Lu To: Bjorn Helgaas , "Rafael J. Wysocki" , Jiang Liu , gregkh@linuxfoundation.org Cc: Gavin Guo , linux-pci@vger.kernel.org, linux-acpi@vger.kernel.org, linux-kernel@vger.kernel.org, Yinghai Lu , rafael.j.wysocki@intel.com, stable@vger.kernel.org Subject: [PATCH v3.9 stable] PCI: acpiphp: Re-enumerate devices when host bridge receives Bus Check Date: Wed, 5 Jun 2013 18:55:53 -0700 Message-Id: <1370483753-2907-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: acsinet21.oracle.com [141.146.126.237] Sender: linux-pci-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pci@vger.kernel.org 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 is as module instead of built-in by Yinghai. [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 CC: stable@vger.kernel.org # v3.9+ --- 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