Merge "Change requested in launchpad bug #1288352" into 5.0
[packages/centos6/qemu.git] / 0618-xhci-add-msix-support.patch
1 From b04ba21e22b2df805af8236bc462c5c403fc6ee4 Mon Sep 17 00:00:00 2001
2 From: Gerd Hoffmann <kraxel@redhat.com>
3 Date: Thu, 30 Aug 2012 12:06:59 +0200
4 Subject: [PATCH] xhci: add msix support
5
6 Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
7 ---
8  hw/usb/hcd-xhci.c | 47 ++++++++++++++++++++++++++++++++++++++++++++++-
9  trace-events      |  3 +++
10  2 files changed, 49 insertions(+), 1 deletion(-)
11
12 diff --git a/hw/usb/hcd-xhci.c b/hw/usb/hcd-xhci.c
13 index 1857f42..777f903 100644
14 --- a/hw/usb/hcd-xhci.c
15 +++ b/hw/usb/hcd-xhci.c
16 @@ -23,6 +23,7 @@
17  #include "hw/usb.h"
18  #include "hw/pci.h"
19  #include "hw/msi.h"
20 +#include "hw/msix.h"
21  #include "trace.h"
22  
23  //#define DEBUG_XHCI
24 @@ -59,6 +60,8 @@
25  #define OFF_OPER        LEN_CAP
26  #define OFF_RUNTIME     0x1000
27  #define OFF_DOORBELL    0x2000
28 +#define OFF_MSIX_TABLE  0x3000
29 +#define OFF_MSIX_PBA    0x3800
30  /* must be power of 2 */
31  #define LEN_REGS        0x4000
32  
33 @@ -411,6 +414,7 @@ struct XHCIState {
34      uint32_t erstba_high;
35      uint32_t erdp_low;
36      uint32_t erdp_high;
37 +    bool     msix_used;
38  
39      int64_t mfindex_start;
40      QEMUTimer *mfwrap_timer;
41 @@ -437,6 +441,7 @@ typedef struct XHCIEvRingSeg {
42  
43  enum xhci_flags {
44      XHCI_FLAG_USE_MSI = 1,
45 +    XHCI_FLAG_USE_MSI_X,
46  };
47  
48  static void xhci_kick_ep(XHCIState *xhci, unsigned int slotid,
49 @@ -616,7 +621,8 @@ static void xhci_intx_update(XHCIState *xhci)
50  {
51      int level = 0;
52  
53 -    if (msi_enabled(&xhci->pci_dev)) {
54 +    if (msix_enabled(&xhci->pci_dev) ||
55 +        msi_enabled(&xhci->pci_dev)) {
56          return;
57      }
58  
59 @@ -630,6 +636,30 @@ static void xhci_intx_update(XHCIState *xhci)
60      qemu_set_irq(xhci->irq, level);
61  }
62  
63 +static void xhci_msix_update(XHCIState *xhci)
64 +{
65 +    bool enabled;
66 +
67 +    if (!msix_enabled(&xhci->pci_dev)) {
68 +        return;
69 +    }
70 +
71 +    enabled = xhci->iman & IMAN_IE;
72 +    if (enabled == xhci->msix_used) {
73 +        return;
74 +    }
75 +
76 +    if (enabled) {
77 +        trace_usb_xhci_irq_msix_use(0);
78 +        msix_vector_use(&xhci->pci_dev, 0);
79 +        xhci->msix_used = true;
80 +    } else {
81 +        trace_usb_xhci_irq_msix_unuse(0);
82 +        msix_vector_unuse(&xhci->pci_dev, 0);
83 +        xhci->msix_used = false;
84 +    }
85 +}
86 +
87  static void xhci_intr_raise(XHCIState *xhci)
88  {
89      if (!(xhci->iman & IMAN_IP) ||
90 @@ -641,6 +671,12 @@ static void xhci_intr_raise(XHCIState *xhci)
91          return;
92      }
93  
94 +    if (msix_enabled(&xhci->pci_dev)) {
95 +        trace_usb_xhci_irq_msix(0);
96 +        msix_notify(&xhci->pci_dev, 0);
97 +        return;
98 +    }
99 +
100      if (msi_enabled(&xhci->pci_dev)) {
101          trace_usb_xhci_irq_msi(0);
102          msi_notify(&xhci->pci_dev, 0);
103 @@ -2282,6 +2318,7 @@ static void xhci_reset(DeviceState *dev)
104      xhci->erstba_high = 0;
105      xhci->erdp_low = 0;
106      xhci->erdp_high = 0;
107 +    xhci->msix_used = 0;
108  
109      xhci->er_ep_idx = 0;
110      xhci->er_pcs = 1;
111 @@ -2590,6 +2627,7 @@ static void xhci_runtime_write(XHCIState *xhci, uint32_t reg, uint32_t val)
112          xhci->iman &= ~IMAN_IE;
113          xhci->iman |= val & IMAN_IE;
114          xhci_intx_update(xhci);
115 +        xhci_msix_update(xhci);
116          break;
117      case 0x24: /* IMOD */
118          xhci->imod = val;
119 @@ -2885,6 +2923,12 @@ static int usb_xhci_initfn(struct PCIDevice *dev)
120      if (xhci->flags & (1 << XHCI_FLAG_USE_MSI)) {
121          msi_init(&xhci->pci_dev, 0x70, MAXINTRS, true, false);
122      }
123 +    if (xhci->flags & (1 << XHCI_FLAG_USE_MSI_X)) {
124 +        msix_init(&xhci->pci_dev, MAXINTRS,
125 +                  &xhci->mem, 0, OFF_MSIX_TABLE,
126 +                  &xhci->mem, 0, OFF_MSIX_PBA,
127 +                  0x90);
128 +    }
129  
130      return 0;
131  }
132 @@ -2896,6 +2940,7 @@ static const VMStateDescription vmstate_xhci = {
133  
134  static Property xhci_properties[] = {
135      DEFINE_PROP_BIT("msi",    XHCIState, flags, XHCI_FLAG_USE_MSI, true),
136 +    DEFINE_PROP_BIT("msix",   XHCIState, flags, XHCI_FLAG_USE_MSI_X, true),
137      DEFINE_PROP_UINT32("p2",  XHCIState, numports_2, 4),
138      DEFINE_PROP_UINT32("p3",  XHCIState, numports_3, 4),
139      DEFINE_PROP_END_OF_LIST(),
140 diff --git a/trace-events b/trace-events
141 index d941e78..f86bbda 100644
142 --- a/trace-events
143 +++ b/trace-events
144 @@ -316,6 +316,9 @@ usb_xhci_runtime_write(uint32_t off, uint32_t val) "off 0x%04x, val 0x%08x"
145  usb_xhci_doorbell_write(uint32_t off, uint32_t val) "off 0x%04x, val 0x%08x"
146  usb_xhci_irq_intx(uint32_t level) "level %d"
147  usb_xhci_irq_msi(uint32_t nr) "nr %d"
148 +usb_xhci_irq_msix(uint32_t nr) "nr %d"
149 +usb_xhci_irq_msix_use(uint32_t nr) "nr %d"
150 +usb_xhci_irq_msix_unuse(uint32_t nr) "nr %d"
151  usb_xhci_queue_event(uint32_t idx, const char *trb, const char *evt, uint64_t param, uint32_t status, uint32_t control) "idx %d, %s, %s, p %016" PRIx64 ", s %08x, c 0x%08x"
152  usb_xhci_fetch_trb(uint64_t addr, const char *name, uint64_t param, uint32_t status, uint32_t control) "addr %016" PRIx64 ", %s, p %016" PRIx64 ", s %08x, c 0x%08x"
153  usb_xhci_slot_enable(uint32_t slotid) "slotid %d"
154 -- 
155 1.7.12.1
156