From nobody Thu Nov 6 14:17:14 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=redhat.com Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1541413657335785.2036325987434; Mon, 5 Nov 2018 02:27:37 -0800 (PST) Received: from localhost ([::1]:34304 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gJc6W-0000m6-3f for importer@patchew.org; Mon, 05 Nov 2018 05:27:32 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:53541) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gJc4G-0007VX-Sw for qemu-devel@nongnu.org; Mon, 05 Nov 2018 05:25:14 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gJc0u-0004UG-9c for qemu-devel@nongnu.org; Mon, 05 Nov 2018 05:21:51 -0500 Received: from mx1.redhat.com ([209.132.183.28]:40354) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1gJc0t-0001Xv-LE; Mon, 05 Nov 2018 05:21:43 -0500 Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.15]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 434F488311; Mon, 5 Nov 2018 10:21:24 +0000 (UTC) Received: from t460s.redhat.com (ovpn-117-149.ams2.redhat.com [10.36.117.149]) by smtp.corp.redhat.com (Postfix) with ESMTP id 948BD5D75D; Mon, 5 Nov 2018 10:21:21 +0000 (UTC) From: David Hildenbrand To: qemu-devel@nongnu.org Date: Mon, 5 Nov 2018 11:20:43 +0100 Message-Id: <20181105102044.20547-10-david@redhat.com> In-Reply-To: <20181105102044.20547-1-david@redhat.com> References: <20181105102044.20547-1-david@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.15 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.28]); Mon, 05 Nov 2018 10:21:24 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PATCH v2 09/10] pci/shpc: perform unplug via the hotplug handler X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Eduardo Habkost , "Michael S . Tsirkin" , Cornelia Huck , David Hildenbrand , Alexander Graf , "Dr . David Alan Gilbert" , Christian Borntraeger , qemu-s390x@nongnu.org, qemu-ppc@nongnu.org, Igor Mammedov , Richard Henderson , David Gibson Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Introduce and use the "unplug" callback. This is a preparation for multi-stage hotplug handlers, whereby the bus hotplug handler is overwritten by the machine hotplug handler. This handler will then pass control to the bus hotplug handler. So to get this running cleanly, we also have to make sure to go via the hotplug handler chain when actually unplugging a device after an unplug request. Lookup the hotplug handler and call "unplug". Signed-off-by: David Hildenbrand Reviewed-by: David Gibson --- hw/pci-bridge/pci_bridge_dev.c | 14 ++++++++++++++ hw/pci-bridge/pcie_pci_bridge.c | 14 ++++++++++++++ hw/pci/shpc.c | 11 ++++++++++- include/hw/pci/shpc.h | 2 ++ 4 files changed, 40 insertions(+), 1 deletion(-) diff --git a/hw/pci-bridge/pci_bridge_dev.c b/hw/pci-bridge/pci_bridge_dev.c index e1df9a52ac..91415f114c 100644 --- a/hw/pci-bridge/pci_bridge_dev.c +++ b/hw/pci-bridge/pci_bridge_dev.c @@ -219,6 +219,19 @@ static void pci_bridge_dev_plug_cb(HotplugHandler *hot= plug_dev, shpc_device_plug_cb(hotplug_dev, dev, errp); } =20 +static void pci_bridge_dev_unplug_cb(HotplugHandler *hotplug_dev, + DeviceState *dev, Error **errp) +{ + PCIDevice *pci_hotplug_dev =3D PCI_DEVICE(hotplug_dev); + + if (!shpc_present(pci_hotplug_dev)) { + error_setg(errp, "standard hotplug controller has been disabled fo= r " + "this %s", TYPE_PCI_BRIDGE_DEV); + return; + } + shpc_device_unplug_cb(hotplug_dev, dev, errp); +} + static void pci_bridge_dev_unplug_request_cb(HotplugHandler *hotplug_dev, DeviceState *dev, Error **err= p) { @@ -251,6 +264,7 @@ static void pci_bridge_dev_class_init(ObjectClass *klas= s, void *data) dc->vmsd =3D &pci_bridge_dev_vmstate; set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories); hc->plug =3D pci_bridge_dev_plug_cb; + hc->unplug =3D pci_bridge_dev_unplug_cb; hc->unplug_request =3D pci_bridge_dev_unplug_request_cb; } =20 diff --git a/hw/pci-bridge/pcie_pci_bridge.c b/hw/pci-bridge/pcie_pci_bridg= e.c index c634353b06..7c667bc97c 100644 --- a/hw/pci-bridge/pcie_pci_bridge.c +++ b/hw/pci-bridge/pcie_pci_bridge.c @@ -150,6 +150,19 @@ static void pcie_pci_bridge_plug_cb(HotplugHandler *ho= tplug_dev, shpc_device_plug_cb(hotplug_dev, dev, errp); } =20 +static void pcie_pci_bridge_unplug_cb(HotplugHandler *hotplug_dev, + DeviceState *dev, Error **errp) +{ + PCIDevice *pci_hotplug_dev =3D PCI_DEVICE(hotplug_dev); + + if (!shpc_present(pci_hotplug_dev)) { + error_setg(errp, "standard hotplug controller has been disabled fo= r " + "this %s", TYPE_PCIE_PCI_BRIDGE_DEV); + return; + } + shpc_device_unplug_cb(hotplug_dev, dev, errp); +} + static void pcie_pci_bridge_unplug_request_cb(HotplugHandler *hotplug_dev, DeviceState *dev, Error **er= rp) { @@ -180,6 +193,7 @@ static void pcie_pci_bridge_class_init(ObjectClass *kla= ss, void *data) dc->reset =3D &pcie_pci_bridge_reset; set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories); hc->plug =3D pcie_pci_bridge_plug_cb; + hc->unplug =3D pcie_pci_bridge_unplug_cb; hc->unplug_request =3D pcie_pci_bridge_unplug_request_cb; } =20 diff --git a/hw/pci/shpc.c b/hw/pci/shpc.c index 098ffaef1d..5de905cb56 100644 --- a/hw/pci/shpc.c +++ b/hw/pci/shpc.c @@ -238,6 +238,7 @@ static void shpc_invalid_command(SHPCDevice *shpc) =20 static void shpc_free_devices_in_slot(SHPCDevice *shpc, int slot) { + HotplugHandler *hotplug_ctrl; int devfn; int pci_slot =3D SHPC_IDX_TO_PCI(slot); for (devfn =3D PCI_DEVFN(pci_slot, 0); @@ -245,7 +246,9 @@ static void shpc_free_devices_in_slot(SHPCDevice *shpc,= int slot) ++devfn) { PCIDevice *affected_dev =3D shpc->sec_bus->devices[devfn]; if (affected_dev) { - object_unparent(OBJECT(affected_dev)); + hotplug_ctrl =3D qdev_get_hotplug_handler(DEVICE(affected_dev)= ); + hotplug_handler_unplug(hotplug_ctrl, DEVICE(affected_dev), + &error_abort); } } } @@ -540,6 +543,12 @@ void shpc_device_plug_cb(HotplugHandler *hotplug_dev, = DeviceState *dev, shpc_interrupt_update(pci_hotplug_dev); } =20 +void shpc_device_unplug_cb(HotplugHandler *hotplug_dev, DeviceState *dev, + Error **errp) +{ + object_unparent(OBJECT(dev)); +} + void shpc_device_unplug_request_cb(HotplugHandler *hotplug_dev, DeviceState *dev, Error **errp) { diff --git a/include/hw/pci/shpc.h b/include/hw/pci/shpc.h index 71293aca58..18f6ec1cd5 100644 --- a/include/hw/pci/shpc.h +++ b/include/hw/pci/shpc.h @@ -47,6 +47,8 @@ void shpc_cap_write_config(PCIDevice *d, uint32_t addr, u= int32_t val, int len); =20 void shpc_device_plug_cb(HotplugHandler *hotplug_dev, DeviceState *dev, Error **errp); +void shpc_device_unplug_cb(HotplugHandler *hotplug_dev, DeviceState *dev, + Error **errp); void shpc_device_unplug_request_cb(HotplugHandler *hotplug_dev, DeviceState *dev, Error **errp); =20 --=20 2.17.2