From: Igor Mammedov <imammedo@redhat.com>
To: qemu-devel@nongnu.org
Cc: peter.crosthwaite@xilinx.com, marcel.a@redhat.com,
mst@redhat.com, aliguori@amazon.com, pbonzini@redhat.com,
afaerber@suse.de
Subject: [Qemu-devel] [PATCH 8/9] pci/pcie: convert PCIE hotplug to use hotplug-handler API
Date: Tue, 14 Jan 2014 17:55:53 +0100 [thread overview]
Message-ID: <1389718554-2387-9-git-send-email-imammedo@redhat.com> (raw)
In-Reply-To: <1389718554-2387-1-git-send-email-imammedo@redhat.com>
Split pcie_cap_slot_hotplug() into hotplug/unplug callbacks
and register them as "hotplug-handler" interface implementation of
PCIE_SLOT device.
Replace pci_bus_hotplug() wiring with setting link on PCI BUS
"hotplug-handler" property to PCI_BRIDGE_DEV device.
Signed-off-by: Igor Mammedov <imammedo@redhat.com>
---
v2:
* keep original non abort behavior of pcie_cap_slot_init()
---
hw/pci/pcie.c | 67 ++++++++++++++++++++++++++++++------------------
hw/pci/pcie_port.c | 8 ++++++
include/hw/pci/pcie.h | 5 +++
3 files changed, 55 insertions(+), 25 deletions(-)
diff --git a/hw/pci/pcie.c b/hw/pci/pcie.c
index ca60cf2..66d234a 100644
--- a/hw/pci/pcie.c
+++ b/hw/pci/pcie.c
@@ -26,6 +26,7 @@
#include "hw/pci/pci_bus.h"
#include "hw/pci/pcie_regs.h"
#include "qemu/range.h"
+#include "qapi/qmp/qerror.h"
//#define DEBUG_PCIE
#ifdef DEBUG_PCIE
@@ -216,28 +217,20 @@ static void pcie_cap_slot_event(PCIDevice *dev, PCIExpressHotPlugEvent event)
hotplug_event_notify(dev);
}
-static int pcie_cap_slot_hotplug(DeviceState *qdev,
- PCIDevice *pci_dev, PCIHotplugState state)
+static void pcie_cap_slot_hotplug_common(PCIDevice *hotplug_dev,
+ DeviceState *dev,
+ uint8_t **exp_cap, Error **errp)
{
- PCIDevice *d = PCI_DEVICE(qdev);
- uint8_t *exp_cap = d->config + d->exp.exp_cap;
- uint16_t sltsta = pci_get_word(exp_cap + PCI_EXP_SLTSTA);
-
- /* Don't send event when device is enabled during qemu machine creation:
- * it is present on boot, no hotplug event is necessary. We do send an
- * event when the device is disabled later. */
- if (state == PCI_COLDPLUG_ENABLED) {
- pci_word_test_and_set_mask(exp_cap + PCI_EXP_SLTSTA,
- PCI_EXP_SLTSTA_PDS);
- return 0;
- }
+ PCIDevice *pci_dev = PCI_DEVICE(dev);
+ *exp_cap = hotplug_dev->config + hotplug_dev->exp.exp_cap;
+ uint16_t sltsta = pci_get_word(*exp_cap + PCI_EXP_SLTSTA);
PCIE_DEV_PRINTF(pci_dev, "hotplug state: %d\n", state);
if (sltsta & PCI_EXP_SLTSTA_EIS) {
/* the slot is electromechanically locked.
* This error is propagated up to qdev and then to HMP/QMP.
*/
- return -EBUSY;
+ error_setg_errno(errp, -EBUSY, "slot is electromechanically locked");
}
/* TODO: multifunction hot-plug.
@@ -245,18 +238,40 @@ static int pcie_cap_slot_hotplug(DeviceState *qdev,
* hot plugged/unplugged.
*/
assert(PCI_FUNC(pci_dev->devfn) == 0);
+}
- if (state == PCI_HOTPLUG_ENABLED) {
+void pcie_cap_slot_hotplug_cb(HotplugHandler *hotplug_dev, DeviceState *dev,
+ Error **errp)
+{
+ uint8_t *exp_cap;
+
+ pcie_cap_slot_hotplug_common(PCI_DEVICE(hotplug_dev), dev, &exp_cap, errp);
+
+ /* Don't send event when device is enabled during qemu machine creation:
+ * it is present on boot, no hotplug event is necessary. We do send an
+ * event when the device is disabled later. */
+ if (!dev->hotplugged) {
pci_word_test_and_set_mask(exp_cap + PCI_EXP_SLTSTA,
PCI_EXP_SLTSTA_PDS);
- pcie_cap_slot_event(d, PCI_EXP_HP_EV_PDC);
- } else {
- object_unparent(OBJECT(pci_dev));
- pci_word_test_and_clear_mask(exp_cap + PCI_EXP_SLTSTA,
- PCI_EXP_SLTSTA_PDS);
- pcie_cap_slot_event(d, PCI_EXP_HP_EV_PDC);
+ return;
}
- return 0;
+
+ pci_word_test_and_set_mask(exp_cap + PCI_EXP_SLTSTA,
+ PCI_EXP_SLTSTA_PDS);
+ pcie_cap_slot_event(PCI_DEVICE(hotplug_dev), PCI_EXP_HP_EV_PDC);
+}
+
+void pcie_cap_slot_hot_unplug_cb(HotplugHandler *hotplug_dev, DeviceState *dev,
+ Error **errp)
+{
+ uint8_t *exp_cap;
+
+ pcie_cap_slot_hotplug_common(PCI_DEVICE(hotplug_dev), dev, &exp_cap, errp);
+
+ object_unparent(OBJECT(dev));
+ pci_word_test_and_clear_mask(exp_cap + PCI_EXP_SLTSTA,
+ PCI_EXP_SLTSTA_PDS);
+ pcie_cap_slot_event(PCI_DEVICE(hotplug_dev), PCI_EXP_HP_EV_PDC);
}
/* pci express slot for pci express root/downstream port
@@ -264,6 +279,7 @@ static int pcie_cap_slot_hotplug(DeviceState *qdev,
void pcie_cap_slot_init(PCIDevice *dev, uint16_t slot)
{
uint32_t pos = dev->exp.exp_cap;
+ BusState *bus = BUS(pci_bridge_get_sec_bus(PCI_BRIDGE(dev)));
pci_word_test_and_set_mask(dev->config + pos + PCI_EXP_FLAGS,
PCI_EXP_FLAGS_SLOT);
@@ -305,8 +321,9 @@ void pcie_cap_slot_init(PCIDevice *dev, uint16_t slot)
dev->exp.hpev_notified = false;
- pci_bus_hotplug(pci_bridge_get_sec_bus(PCI_BRIDGE(dev)),
- pcie_cap_slot_hotplug, &dev->qdev);
+ bus->allow_hotplug = 1;
+ object_property_set_link(OBJECT(bus), OBJECT(dev),
+ QDEV_HOTPLUG_HANDLER_PROPERTY, NULL);
}
void pcie_cap_slot_reset(PCIDevice *dev)
diff --git a/hw/pci/pcie_port.c b/hw/pci/pcie_port.c
index 2adb030..fa24877 100644
--- a/hw/pci/pcie_port.c
+++ b/hw/pci/pcie_port.c
@@ -19,6 +19,7 @@
*/
#include "hw/pci/pcie_port.h"
+#include "hw/hotplug.h"
void pcie_port_init_reg(PCIDevice *d)
{
@@ -149,8 +150,11 @@ static Property pcie_slot_props[] = {
static void pcie_slot_class_init(ObjectClass *oc, void *data)
{
DeviceClass *dc = DEVICE_CLASS(oc);
+ HotplugHandlerClass *hc = HOTPLUG_HANDLER_CLASS(oc);
dc->props = pcie_slot_props;
+ hc->plug = pcie_cap_slot_hotplug_cb;
+ hc->unplug = pcie_cap_slot_hot_unplug_cb;
}
static const TypeInfo pcie_slot_type_info = {
@@ -159,6 +163,10 @@ static const TypeInfo pcie_slot_type_info = {
.instance_size = sizeof(PCIESlot),
.abstract = true,
.class_init = pcie_slot_class_init,
+ .interfaces = (InterfaceInfo[]) {
+ { TYPE_HOTPLUG_HANDLER },
+ { }
+ }
};
static void pcie_port_register_types(void)
diff --git a/include/hw/pci/pcie.h b/include/hw/pci/pcie.h
index 1966169..b0bf7e3 100644
--- a/include/hw/pci/pcie.h
+++ b/include/hw/pci/pcie.h
@@ -25,6 +25,7 @@
#include "hw/pci/pci_regs.h"
#include "hw/pci/pcie_regs.h"
#include "hw/pci/pcie_aer.h"
+#include "hw/hotplug.h"
typedef enum {
/* for attention and power indicator */
@@ -122,4 +123,8 @@ extern const VMStateDescription vmstate_pcie_device;
.offset = vmstate_offset_value(_state, _field, PCIDevice), \
}
+void pcie_cap_slot_hotplug_cb(HotplugHandler *hotplug_dev, DeviceState *dev,
+ Error **errp);
+void pcie_cap_slot_hot_unplug_cb(HotplugHandler *hotplug_dev, DeviceState *dev,
+ Error **errp);
#endif /* QEMU_PCIE_H */
--
1.7.1
next prev parent reply other threads:[~2014-01-14 17:01 UTC|newest]
Thread overview: 15+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-01-14 16:55 [Qemu-devel] [PATCH 0/9 v4] Refactor PCI/SHPC/PCIE hotplug to use a more generic hotplug API Igor Mammedov
2014-01-14 16:55 ` [Qemu-devel] [PATCH 1/9] define hotplug interface Igor Mammedov
2014-01-14 16:55 ` [Qemu-devel] [PATCH 2/9] qdev: add to BusState "hotplug-handler" link Igor Mammedov
2014-01-14 16:55 ` [Qemu-devel] [PATCH 3/9] qdev: add "hotpluggable" property to Device Igor Mammedov
2014-01-14 16:55 ` [Qemu-devel] [PATCH 4/9] hw/acpi: move typeinfo to the file end Igor Mammedov
2014-01-14 16:55 ` [Qemu-devel] [PATCH 5/9] qdev:pci: refactor PCIDevice to use generic "hotpluggable" property Igor Mammedov
2014-01-14 16:55 ` [Qemu-devel] [PATCH 6/9] acpi/piix4pm: convert ACPI PCI hotplug to use hotplug-handler API Igor Mammedov
2014-01-14 16:55 ` [Qemu-devel] [PATCH 7/9] pci/shpc: convert SHPC " Igor Mammedov
2014-01-14 16:55 ` Igor Mammedov [this message]
2014-01-14 16:55 ` [Qemu-devel] [PATCH 9/9] hw/pci: switch to a generic hotplug handling for PCIDevice Igor Mammedov
2014-01-20 11:36 ` Michael S. Tsirkin
2014-01-20 12:45 ` Igor Mammedov
2014-01-20 12:57 ` Paolo Bonzini
2014-01-16 9:33 ` [Qemu-devel] [PATCH 0/9 v4] Refactor PCI/SHPC/PCIE hotplug to use a more generic hotplug API Michael S. Tsirkin
2014-01-16 9:38 ` Igor Mammedov
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1389718554-2387-9-git-send-email-imammedo@redhat.com \
--to=imammedo@redhat.com \
--cc=afaerber@suse.de \
--cc=aliguori@amazon.com \
--cc=marcel.a@redhat.com \
--cc=mst@redhat.com \
--cc=pbonzini@redhat.com \
--cc=peter.crosthwaite@xilinx.com \
--cc=qemu-devel@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.