|
@@ -2222,6 +2222,11 @@ static void virtio_pci_realize(PCIDevice *pci_dev, Error **errp)
|
|
pcie_cap_lnkctl_init(pci_dev);
|
|
pcie_cap_lnkctl_init(pci_dev);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ if (proxy->flags & VIRTIO_PCI_FLAG_PM_NO_SOFT_RESET) {
|
|
|
|
+ pci_set_word(pci_dev->config + pos + PCI_PM_CTRL,
|
|
|
|
+ PCI_PM_CTRL_NO_SOFT_RESET);
|
|
|
|
+ }
|
|
|
|
+
|
|
if (proxy->flags & VIRTIO_PCI_FLAG_INIT_PM) {
|
|
if (proxy->flags & VIRTIO_PCI_FLAG_INIT_PM) {
|
|
/* Init Power Management Control Register */
|
|
/* Init Power Management Control Register */
|
|
pci_set_word(pci_dev->wmask + pos + PCI_PM_CTRL,
|
|
pci_set_word(pci_dev->wmask + pos + PCI_PM_CTRL,
|
|
@@ -2284,11 +2289,33 @@ static void virtio_pci_reset(DeviceState *qdev)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+static bool virtio_pci_no_soft_reset(PCIDevice *dev)
|
|
|
|
+{
|
|
|
|
+ uint16_t pmcsr;
|
|
|
|
+
|
|
|
|
+ if (!pci_is_express(dev) || !dev->exp.pm_cap) {
|
|
|
|
+ return false;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ pmcsr = pci_get_word(dev->config + dev->exp.pm_cap + PCI_PM_CTRL);
|
|
|
|
+
|
|
|
|
+ /*
|
|
|
|
+ * When No_Soft_Reset bit is set and the device
|
|
|
|
+ * is in D3hot state, don't reset device
|
|
|
|
+ */
|
|
|
|
+ return (pmcsr & PCI_PM_CTRL_NO_SOFT_RESET) &&
|
|
|
|
+ (pmcsr & PCI_PM_CTRL_STATE_MASK) == 3;
|
|
|
|
+}
|
|
|
|
+
|
|
static void virtio_pci_bus_reset_hold(Object *obj, ResetType type)
|
|
static void virtio_pci_bus_reset_hold(Object *obj, ResetType type)
|
|
{
|
|
{
|
|
PCIDevice *dev = PCI_DEVICE(obj);
|
|
PCIDevice *dev = PCI_DEVICE(obj);
|
|
DeviceState *qdev = DEVICE(obj);
|
|
DeviceState *qdev = DEVICE(obj);
|
|
|
|
|
|
|
|
+ if (virtio_pci_no_soft_reset(dev)) {
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+
|
|
virtio_pci_reset(qdev);
|
|
virtio_pci_reset(qdev);
|
|
|
|
|
|
if (pci_is_express(dev)) {
|
|
if (pci_is_express(dev)) {
|
|
@@ -2328,6 +2355,8 @@ static Property virtio_pci_properties[] = {
|
|
VIRTIO_PCI_FLAG_INIT_LNKCTL_BIT, true),
|
|
VIRTIO_PCI_FLAG_INIT_LNKCTL_BIT, true),
|
|
DEFINE_PROP_BIT("x-pcie-pm-init", VirtIOPCIProxy, flags,
|
|
DEFINE_PROP_BIT("x-pcie-pm-init", VirtIOPCIProxy, flags,
|
|
VIRTIO_PCI_FLAG_INIT_PM_BIT, true),
|
|
VIRTIO_PCI_FLAG_INIT_PM_BIT, true),
|
|
|
|
+ DEFINE_PROP_BIT("x-pcie-pm-no-soft-reset", VirtIOPCIProxy, flags,
|
|
|
|
+ VIRTIO_PCI_FLAG_PM_NO_SOFT_RESET_BIT, false),
|
|
DEFINE_PROP_BIT("x-pcie-flr-init", VirtIOPCIProxy, flags,
|
|
DEFINE_PROP_BIT("x-pcie-flr-init", VirtIOPCIProxy, flags,
|
|
VIRTIO_PCI_FLAG_INIT_FLR_BIT, true),
|
|
VIRTIO_PCI_FLAG_INIT_FLR_BIT, true),
|
|
DEFINE_PROP_BIT("aer", VirtIOPCIProxy, flags,
|
|
DEFINE_PROP_BIT("aer", VirtIOPCIProxy, flags,
|