From 8d6999516c9f053ee6f9113e83453a6587576729 Mon Sep 17 00:00:00 2001
From: Dr. David Alan Gilbert (git) <dgilbert@redhat.com>
Date: Thu, 11 Sep 2014 12:25:44 +0200
Subject: [PATCH 14/15] xhci PCIe endpoint migration compatibility fix

Message-id: <1410438345-22590-2-git-send-email-dgilbert@redhat.com>
Patchwork-id: 61008
O-Subject: [RHEV-7.1 qemu-kvm-rhev PATCH 1/2] xhci PCIe endpoint migration compatibility fix
Bugzilla: 1138579
RH-Acked-by: Alex Williamson <alex.williamson@redhat.com>
RH-Acked-by: Gerd Hoffmann <kraxel@redhat.com>
RH-Acked-by: Michael S. Tsirkin <mst@redhat.com>

From: "Dr. David Alan Gilbert" <dgilbert@redhat.com>

Add back the PCIe config capabilities on XHCI cards in non-PCIe slots,
but only for machine types before 2.1.

This fixes a migration incompatibility in the XHCI PCI devices
caused by:
   058fdcf52cdbf57b67e7 - xhci: add endpoint cap on express bus only

Note that in fixing it for compatibility with older QEMUs, it breaks
compatibility with existing QEMU 2.1's on older machine types.

The status before this patch was (if it used an XHCI adapter):
   machine type | source qemu
     any           pre-2.1     - FAIL
     any           2.1...      - PASS

With this patch:
   machine type | source qemu
     any           pre-2.1    - PASS
     pre-2.1       2.1...     - FAIL
     2.1           2.1...     - PASS

A test to trigger it is to add '-device nec-usb-xhci,id=xhci,addr=0x12'
to the command line.

Cc: qemu-stable@nongnu.org
Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
Acked-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
(cherry picked from commit e6043e92c2812a56b8f6cf35d5512067c746ce21)

Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
---
 hw/usb/hcd-xhci.c    |    6 +++++-
 include/hw/i386/pc.h |    5 +++++
 2 files changed, 10 insertions(+), 1 deletions(-)

diff --git a/hw/usb/hcd-xhci.c b/hw/usb/hcd-xhci.c
index 051f574..ea7edbd 100644
--- a/hw/usb/hcd-xhci.c
+++ b/hw/usb/hcd-xhci.c
@@ -501,6 +501,7 @@ enum xhci_flags {
     XHCI_FLAG_USE_MSI = 1,
     XHCI_FLAG_USE_MSI_X,
     XHCI_FLAG_SS_FIRST,
+    XHCI_FLAG_FORCE_PCIE_ENDCAP,
 };
 
 static void xhci_kick_ep(XHCIState *xhci, unsigned int slotid,
@@ -3628,7 +3629,8 @@ static int usb_xhci_initfn(struct PCIDevice *dev)
                      PCI_BASE_ADDRESS_SPACE_MEMORY|PCI_BASE_ADDRESS_MEM_TYPE_64,
                      &xhci->mem);
 
-    if (pci_bus_is_express(dev->bus)) {
+    if (pci_bus_is_express(dev->bus) ||
+        xhci_get_flag(xhci, XHCI_FLAG_FORCE_PCIE_ENDCAP)) {
         ret = pcie_endpoint_cap_init(dev, 0xa0);
         assert(ret >= 0);
     }
@@ -3838,6 +3840,8 @@ static Property xhci_properties[] = {
     DEFINE_PROP_BIT("msix",     XHCIState, flags, XHCI_FLAG_USE_MSI_X, true),
     DEFINE_PROP_BIT("superspeed-ports-first",
                     XHCIState, flags, XHCI_FLAG_SS_FIRST, true),
+    DEFINE_PROP_BIT("force-pcie-endcap", XHCIState, flags,
+                    XHCI_FLAG_FORCE_PCIE_ENDCAP, false),
     DEFINE_PROP_UINT32("intrs", XHCIState, numintrs, MAXINTRS),
     DEFINE_PROP_UINT32("slots", XHCIState, numslots, MAXSLOTS),
     DEFINE_PROP_UINT32("p2",    XHCIState, numports_2, 4),
diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h
index 9e15ff1..aa6ddc4 100644
--- a/include/hw/i386/pc.h
+++ b/include/hw/i386/pc.h
@@ -316,6 +316,11 @@ bool e820_get_entry(int, uint32_t, uint64_t *, uint64_t *);
             .value    = "off",\
         },\
         {\
+            .driver   = "nec-usb-xhci",\
+            .property = "force-pcie-endcap",\
+            .value    = "on",\
+        },\
+        {\
             .driver   = "pci-serial",\
             .property = "prog_if",\
             .value    = stringify(0),\
-- 
1.7.1

