From patchwork Tue Aug 7 16:10:50 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jiang Liu X-Patchwork-Id: 1286911 X-Patchwork-Delegate: bhelgaas@google.com Return-Path: X-Original-To: patchwork-linux-pci@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork1.kernel.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by patchwork1.kernel.org (Postfix) with ESMTP id 642B53FC23 for ; Tue, 7 Aug 2012 16:23:39 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755584Ab2HGQUM (ORCPT ); Tue, 7 Aug 2012 12:20:12 -0400 Received: from mail-pb0-f46.google.com ([209.85.160.46]:51364 "EHLO mail-pb0-f46.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1755601Ab2HGQUH (ORCPT ); Tue, 7 Aug 2012 12:20:07 -0400 Received: by mail-pb0-f46.google.com with SMTP id rr13so4529963pbb.19 for ; Tue, 07 Aug 2012 09:20:07 -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=UcgIKHs6ZN19ZGFDCdz3fsXdn/XleNToMS2xZHQ0EUA=; b=rkCdTgYpFiTDz8CLK+cYJ5nd4nRsOYUo6t/GoNdgKUyIclg+nbng5SOlStkawx1S/M oTzGUj/e26K9DrmvDRWno3l9Ie2AepKC8LUZ7JNYADV5MsHfXLL6Fb3V+4J3ajoVqg+A TK6P6FDqRv8sTpttNQxNFhz+GUV4kSloOMD9+lsY4530KfqYXETzzvTtqJtDZHRcRmxe qefBnB7gTP4Qd6IA49+455A5LfazA6Tj5v7WkgeifSLptVUfJ+MdsDxGFpMeMMqCqIYx 3j8kvY0AeSUByr7AsW0ylFl9ugliyvTuFsGXqc733RzvebHAiqTEFDelYVHgu08MnCyH b9NA== Received: by 10.68.130.67 with SMTP id oc3mr28840378pbb.18.1344356407296; Tue, 07 Aug 2012 09:20:07 -0700 (PDT) Received: from localhost.localdomain ([58.250.81.2]) by mx.google.com with ESMTPS id pt2sm11429362pbb.58.2012.08.07.09.19.58 (version=TLSv1/SSLv3 cipher=OTHER); Tue, 07 Aug 2012 09:20:06 -0700 (PDT) From: Jiang Liu To: Bjorn Helgaas , Don Dutile , Yinghai Lu , Greg KH , Kenji Kaneshige Cc: Jiang Liu , Taku Izumi , "Rafael J . Wysocki" , Yijing Wang , Xinwei Hu , linux-kernel@vger.kernel.org, linux-pci@vger.kernel.org, Jiang Liu Subject: [RFC PATCH v1 10/22] PCI: enhance PCI bus specific logic to support PCI bus lock mechanism Date: Wed, 8 Aug 2012 00:10:50 +0800 Message-Id: <1344355862-2726-11-git-send-email-jiang.liu@huawei.com> X-Mailer: git-send-email 1.7.9.5 In-Reply-To: <1344355862-2726-1-git-send-email-jiang.liu@huawei.com> References: <1344355862-2726-1-git-send-email-jiang.liu@huawei.com> Sender: linux-pci-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pci@vger.kernel.org This patch enhances PCI bus specific logic to support PCI bus lock mechanism. Signed-off-by: Jiang Liu --- drivers/pci/bus.c | 54 ++++++++++++++++++++++++++++++----------------------- 1 file changed, 31 insertions(+), 23 deletions(-) diff --git a/drivers/pci/bus.c b/drivers/pci/bus.c index b6aacaa..371f20a 100644 --- a/drivers/pci/bus.c +++ b/drivers/pci/bus.c @@ -185,19 +185,20 @@ int pci_bus_add_device(struct pci_dev *dev) */ int pci_bus_add_child(struct pci_bus *bus) { - int retval; - - if (bus->bridge) - bus->dev.parent = bus->bridge; - - retval = device_add(&bus->dev); - if (retval) - return retval; - - bus->is_added = 1; - - /* Create legacy_io and legacy_mem files for this bus */ - pci_create_legacy_files(bus); + int retval = -EBUSY; + + if (pci_bus_get_state(bus) == PCI_BUS_STATE_INITIALIZED) { + if (bus->bridge) + bus->dev.parent = bus->bridge; + retval = device_add(&bus->dev); + if (retval == 0) { + /* Create legacy_io and legacy_mem files for this bus */ + pci_create_legacy_files(bus); + pci_bus_change_state(bus, PCI_BUS_STATE_INITIALIZED, + PCI_BUS_STATE_WORKING, false); + bus->is_added = 1; + } + } return retval; } @@ -232,13 +233,14 @@ void pci_bus_add_devices(const struct pci_bus *bus) list_for_each_entry(dev, &bus->devices, bus_list) { BUG_ON(!dev->is_added); - child = dev->subordinate; + child = pci_lock_subordinate(dev, PCI_BUS_STATE_STOPPING - 1); + if (!child) + continue; + /* * If there is an unattached subordinate bus, attach * it and then scan for unattached PCI devices. */ - if (!child) - continue; if (list_empty(&child->node)) { down_write(&pci_bus_sem); list_add_tail(&child->node, &dev->bus->children); @@ -250,28 +252,34 @@ void pci_bus_add_devices(const struct pci_bus *bus) * register the bus with sysfs as the parent is now * properly registered. */ - if (child->is_added) - continue; - retval = pci_bus_add_child(child); - if (retval) - dev_err(&dev->dev, "Error adding bus, continuing\n"); + if (pci_bus_get_state(child) == PCI_BUS_STATE_INITIALIZED) { + retval = pci_bus_add_child(child); + if (retval) + dev_err(&dev->dev, + "Error adding bus, continuing\n"); + } + + pci_bus_unlock(child); } } void pci_enable_bridges(struct pci_bus *bus) { struct pci_dev *dev; + struct pci_bus *child; int retval; list_for_each_entry(dev, &bus->devices, bus_list) { - if (dev->subordinate) { + child = pci_lock_subordinate(dev, PCI_BUS_STATE_STOPPING - 1); + if (child) { if (!pci_is_enabled(dev)) { retval = pci_enable_device(dev); if (retval) dev_err(&dev->dev, "Error enabling bridge (%d), continuing\n", retval); pci_set_master(dev); } - pci_enable_bridges(dev->subordinate); + pci_enable_bridges(child); + pci_bus_unlock(child); } } }