From patchwork Wed May 23 04:35:11 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bjorn Helgaas X-Patchwork-Id: 160810 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id 5D1BEB7008 for ; Wed, 23 May 2012 14:35:53 +1000 (EST) Received: from localhost ([::1]:34676 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1SX3Id-00070B-8s for incoming@patchwork.ozlabs.org; Wed, 23 May 2012 00:35:51 -0400 Received: from eggs.gnu.org ([208.118.235.92]:37998) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1SX3I5-0005hK-VB for qemu-devel@nongnu.org; Wed, 23 May 2012 00:35:20 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1SX3I3-00077M-2d for qemu-devel@nongnu.org; Wed, 23 May 2012 00:35:17 -0400 Received: from mail-fa0-f73.google.com ([209.85.161.73]:55786) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1SX3I2-00076Q-Kv for qemu-devel@nongnu.org; Wed, 23 May 2012 00:35:14 -0400 Received: by faas14 with SMTP id s14so440883faa.4 for ; Tue, 22 May 2012 21:35:12 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20120113; h=subject:to:from:cc:date:message-id:in-reply-to:references :user-agent:mime-version:content-type:content-transfer-encoding; bh=DtlabM7/a1Sw2FpljEuDwuVZEUVDGUODUe/rGlD5nTo=; b=LWiAj/w9iqnWH6mJiGZ7NthDpI0EDhVplZQpLC7mQ3y4GijABY/DIjdhc0xoxlXphL Gt9eJSsbu/MOVf2/aq2ZhxxhAesKSVkSXrixlvYIg4umMy4JtUbFE4QmE+D0NRd2YEgO BwMIBlLdbaQ/i94FLIRnAWGJffoypkRKY5jAYyCJNyRKe+FnYqLMdV943V5t99F/jjtv kwb4GOEBS9PMUX1TDj+LKN0q4pIKS52t4GqUTkr/Mpdvq516VlDkl2hxaIIvTpIJEkFa XSSM22InzM3U+F44j1gLRIc9X+D8d7QLkKn0zaSoSfeaccT/Mv2mv2drdWPC+38G0IG9 LCcQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20120113; h=subject:to:from:cc:date:message-id:in-reply-to:references :user-agent:mime-version:content-type:content-transfer-encoding :x-gm-message-state; bh=DtlabM7/a1Sw2FpljEuDwuVZEUVDGUODUe/rGlD5nTo=; b=Qoncs4zlHBpijp4sNDp5aDYAtsdAj8J0W2KT4duPcWK8LdRRBJropQl65MBXmy84RP udzdXzVEZyF+WJqhpftm6iPrrIGgeo2ukcVlIQcJ26Jio/eWywFNvXtks0vSu0Vdlu3P FzAKzHD75IoGrd20hM2JtXl6Ojfs1PYZIOpEjVMjxkNGkXIewVT8j0wSjRoMAB8U6QAR wmjdmSN3ge789IuknJfoWOEdwXlLypP5GVX7vlpQrKVOvlFPFWK43GZYkT+V6Bfz5bQ+ 4/0cfPeVaPjpaaL/R/4aOqexSxYwN395wEXqNMZ3x0WjIzmOVT5xFK/wHn7ngVYdRHnD hZXw== Received: by 10.14.100.75 with SMTP id y51mr6442325eef.2.1337747712474; Tue, 22 May 2012 21:35:12 -0700 (PDT) Received: by 10.14.100.75 with SMTP id y51mr6442314eef.2.1337747712387; Tue, 22 May 2012 21:35:12 -0700 (PDT) Received: from hpza10.eem.corp.google.com ([74.125.121.33]) by gmr-mx.google.com with ESMTPS id b16si23303336eeg.3.2012.05.22.21.35.12 (version=TLSv1/SSLv3 cipher=AES128-SHA); Tue, 22 May 2012 21:35:12 -0700 (PDT) Received: from bhelgaas.mtv.corp.google.com (bhelgaas.mtv.corp.google.com [172.18.96.155]) by hpza10.eem.corp.google.com (Postfix) with ESMTP id 33B1B200057; Tue, 22 May 2012 21:35:12 -0700 (PDT) Received: from bhelgaas.mtv.corp.google.com (unknown [IPv6:::1]) by bhelgaas.mtv.corp.google.com (Postfix) with ESMTP id 9143E180171; Tue, 22 May 2012 21:35:11 -0700 (PDT) To: Amos Kong From: Bjorn Helgaas Date: Tue, 22 May 2012 22:35:11 -0600 Message-ID: <20120523043511.13449.22006.stgit@bhelgaas.mtv.corp.google.com> In-Reply-To: <20120523043347.13449.1063.stgit@bhelgaas.mtv.corp.google.com> References: <20120523043347.13449.1063.stgit@bhelgaas.mtv.corp.google.com> User-Agent: StGit/0.15 MIME-Version: 1.0 X-Gm-Message-State: ALoCoQkODkT9njDb+VWP8ngUOYLFCN1isx0Pwfita+BZvoRQSoNJW/s7rkVkdGLZuLL6Ll8Ftr9LP6IBHIKa4buIT4dcItvgi6iW7rSfiZXdp/OKERE1TkjaKONzHxaGvZeMsjoZlgddDJmsByT23S8O7XCP4IX4Pg== X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 209.85.161.73 Cc: linux-pci@vger.kernel.org, kaneshige.kenji@jp.fujitsu.com, qemu-devel@nongnu.org, jbarnes@virtuousgeek.org, liuj97@gmail.com Subject: [Qemu-devel] [PATCH v6 2/2] PCI: acpiphp: remove all functions in slot, even without ACPI _EJx X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org From: Amos Kong When we add a device with acpiphp, we enumerate all functions in the slot with pci_scan_slot(), regardless of whether they have associated ACPI methods such as _EJ0. When removing the device, we previously removed only the functions with those ACPI methods. This patch makes the remove symmetric with the add: we remove all functions in the slot, whether they have associated ACPI methods or not. With qemu-kvm and SeaBIOS, we can build a multi-function device where only function 0 has _EJ0 and _ADR (see bugzilla below). Removing and re-adding that device works correctly with Windows guests. This patch makes it also work in Linux guests. [bhelgaas: restructure loop iteration, pull out of slot->funcs loop] Reference: https://bugzilla.kernel.org/show_bug.cgi?id=43219 Signed-off-by: Amos Kong Signed-off-by: Bjorn Helgaas --- drivers/pci/hotplug/acpiphp_glue.c | 39 +++++++++++++++++++++++++++--------- 1 files changed, 29 insertions(+), 10 deletions(-) diff --git a/drivers/pci/hotplug/acpiphp_glue.c b/drivers/pci/hotplug/acpiphp_glue.c index c8f9991..9aff4f0 100644 --- a/drivers/pci/hotplug/acpiphp_glue.c +++ b/drivers/pci/hotplug/acpiphp_glue.c @@ -878,6 +878,21 @@ static void disable_bridges(struct pci_bus *bus) } } +/* return first device in slot, acquiring a reference on it */ +static struct pci_dev *dev_in_slot(struct acpiphp_slot *slot) +{ + struct pci_bus *bus = slot->bridge->pci_bus; + struct pci_dev *dev; + + down_read(&pci_bus_sem); + list_for_each_entry(dev, &bus->devices, bus_list) + if (PCI_SLOT(dev->devfn) == slot->device) + return pci_dev_get(dev); + up_read(&pci_bus_sem); + + return NULL; +} + /** * disable_device - disable a slot * @slot: ACPI PHP slot @@ -902,18 +917,22 @@ static int disable_device(struct acpiphp_slot *slot) (u32)1, NULL, NULL); func->bridge = NULL; } + } - pdev = pci_get_slot(slot->bridge->pci_bus, - PCI_DEVFN(slot->device, func->function)); - if (pdev) { - pci_stop_bus_device(pdev); - if (pdev->subordinate) { - disable_bridges(pdev->subordinate); - pci_disable_device(pdev); - } - __pci_remove_bus_device(pdev); - pci_dev_put(pdev); + /* + * enable_device() enumerates all functions in this device via + * pci_scan_slot(), whether they have associated ACPI hotplug + * methods (_EJ0, etc.) or not. Therefore, we remove all functions + * here. + */ + while ((pdev = dev_in_slot(slot))) { + pci_stop_bus_device(pdev); + if (pdev->subordinate) { + disable_bridges(pdev->subordinate); + pci_disable_device(pdev); } + __pci_remove_bus_device(pdev); + pci_dev_put(pdev); } list_for_each_entry(func, &slot->funcs, sibling) {