From patchwork Wed Aug 22 15:16:45 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jiang Liu X-Patchwork-Id: 1362151 X-Patchwork-Delegate: bhelgaas@google.com Return-Path: X-Original-To: patchwork-linux-pci@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork2.kernel.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by patchwork2.kernel.org (Postfix) with ESMTP id 5F326DFFCC for ; Wed, 22 Aug 2012 15:18:34 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932670Ab2HVPS2 (ORCPT ); Wed, 22 Aug 2012 11:18:28 -0400 Received: from mail-pb0-f46.google.com ([209.85.160.46]:61410 "EHLO mail-pb0-f46.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S932909Ab2HVPSZ (ORCPT ); Wed, 22 Aug 2012 11:18:25 -0400 Received: by pbbrr13 with SMTP id rr13so1627112pbb.19 for ; Wed, 22 Aug 2012 08:18:24 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=from:to:cc:subject:date:message-id:x-mailer:in-reply-to:references; bh=dnEmJtVKXwHcw9GUjNzzomYGeu1lL6PvW/5EdfcsF/o=; b=FyJ+WWzJV3LdyJZ+gTuVIybZfUYK2ypEhe99/z4IS4xguS9y2zo7M8ZRf3H6DzTLQH tY5TbwlNEJRWULCzRJa/cRiIe7s2UB+vFGiSLGbeP/+MSJwuLl1VS/6Anj/yRmhO0JU8 frSbqpsz431gH1EDijeAdFeFZzxjsPI4OvaO+cJKsgNzttMQYac+LCUUnlJmrUdWwPoK faXGekgUVq5lA/Z0XeXs80D2isGIMcrKrLBMP3ajq/5nJOe0vHqN4IVFCixQkM4Ef9si CpZfAAk10LHfbfmJAgKa4ZqPHjXQotL49jF+r4EzKlzSERpNNEB4HevGLpPMvkc9qyVS J6Jw== Received: by 10.68.125.133 with SMTP id mq5mr54256990pbb.42.1345648704857; Wed, 22 Aug 2012 08:18:24 -0700 (PDT) Received: from localhost.localdomain ([221.221.16.29]) by mx.google.com with ESMTPS id uu10sm3917788pbc.2.2012.08.22.08.18.17 (version=TLSv1/SSLv3 cipher=OTHER); Wed, 22 Aug 2012 08:18:23 -0700 (PDT) From: Jiang Liu To: Bjorn Helgaas Cc: Jiang Liu , "Rafael J . Wysocki" , Yijing Wang , linux-kernel@vger.kernel.org, linux-pci@vger.kernel.org, Jiang Liu Subject: [PATCH v2] PCI: allow acpiphp to handle PCIe ports w/o native PCIe hotplug capability Date: Wed, 22 Aug 2012 23:16:45 +0800 Message-Id: <1345648605-7636-1-git-send-email-jiang.liu@huawei.com> X-Mailer: git-send-email 1.7.9.5 In-Reply-To: References: Sender: linux-pci-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pci@vger.kernel.org From: Jiang Liu Commit 0d52f54e2ef64c189dedc332e680b2eb4a34590a (PCI / ACPI: Make acpiphp ignore root bridges using PCIe native hotplug) added code that made the acpiphp driver completely ignore PCIe root complexes for which the kernel had been granted control of the native PCIe hotplug feature by the BIOS through _OSC. Later commit 619a5182d1f38a3d629ee48e04fa182ef9170052 "PCI hotplug: Always allow acpiphp to handle non-PCIe bridges" relaxed the constraints to allow acpiphp driver handle non-PCIe bridges under such a complex. The constraint needs to be relaxed further to allow acpiphp driver to hanlde PCIe ports without native PCIe hotplug capability. Some MR-IOV switch chipsets, such PLX8696, support multiple virtual PCIe switches and may migrate downstream ports among virtual switches. To migrate a downstream port from the source virtual switch to the target, the port needs to be hot-removed from the source and hot-added into the target. pciehp driver can't be used here because there's no slots within the virtual PCIe switch. So acpiphp driver is used to support downstream port migration. A typical configuration is as below: [Root w/o native PCIe HP] [Upstream port of vswitch w/o native PCIe HP] [Downstream port of vswitch w/ native PCIe HP] [PCIe enpoint] Here acpiphp driver will be used to handle root ports and upstream port in the virtual switch, and pciehp driver will be used to handle downstream ports in the virtual switch. v1->v2: use PCIe capability accessors to read PCI_EXP_SLTCAP register Acked-by: Rafael J. Wysocki Signed-off-by: Jiang Liu --- drivers/pci/hotplug/acpiphp_glue.c | 41 +++++++++++++++++++++++++++--------- 1 file changed, 31 insertions(+), 10 deletions(-) diff --git a/drivers/pci/hotplug/acpiphp_glue.c b/drivers/pci/hotplug/acpiphp_glue.c index ad6fd66..e6da392 100644 --- a/drivers/pci/hotplug/acpiphp_glue.c +++ b/drivers/pci/hotplug/acpiphp_glue.c @@ -115,6 +115,35 @@ static const struct acpi_dock_ops acpiphp_dock_ops = { .handler = handle_hotplug_event_func, }; +/* Check whether the PCI device is managed by native PCIe hotplug driver */ +static bool device_is_managed_by_native_pciehp(struct pci_dev *pdev) +{ + u32 reg32; + acpi_handle tmp; + struct acpi_pci_root *root; + + /* Check whether the PCIe port supports native PCIe hotplug */ + if (pcie_capability_read_dword(pdev, PCI_EXP_SLTCAP, ®32)) + return false; + if (!(reg32 & PCI_EXP_SLTCAP_HPC)) + return false; + + /* + * Check whether native PCIe hotplug has been enabled for + * this PCIe hierarchy. + */ + tmp = acpi_find_root_bridge_handle(pdev); + if (!tmp) + return false; + root = acpi_pci_find_root(tmp); + if (!root) + return false; + if (!(root->osc_control_set & OSC_PCI_EXPRESS_NATIVE_HP_CONTROL)) + return false; + + return true; +} + /* callback routine to register each ACPI PCI slot object */ static acpi_status register_slot(acpi_handle handle, u32 lvl, void *context, void **rv) @@ -142,16 +171,8 @@ register_slot(acpi_handle handle, u32 lvl, void *context, void **rv) function = adr & 0xffff; pdev = pbus->self; - if (pdev && pci_is_pcie(pdev)) { - tmp = acpi_find_root_bridge_handle(pdev); - if (tmp) { - struct acpi_pci_root *root = acpi_pci_find_root(tmp); - - if (root && (root->osc_control_set & - OSC_PCI_EXPRESS_NATIVE_HP_CONTROL)) - return AE_OK; - } - } + if (pdev && device_is_managed_by_native_pciehp(pdev)) + return AE_OK; newfunc = kzalloc(sizeof(struct acpiphp_func), GFP_KERNEL); if (!newfunc)