peterdelevoryas / rpms / qemu

Forked from rpms/qemu 2 years ago
Clone

Blame 0346-xhci-rework-interrupt-handling.patch

c8dfc6
From da881a3422ae525f1d0a24f61117a47473261037 Mon Sep 17 00:00:00 2001
c8dfc6
From: Gerd Hoffmann <kraxel@redhat.com>
c8dfc6
Date: Thu, 30 Aug 2012 13:05:10 +0200
c8dfc6
Subject: [PATCH 346/366] xhci: rework interrupt handling
c8dfc6
c8dfc6
Split xhci_irq_update into a function which handles intx updates
c8dfc6
(including lowering the irq line once the guests acks the interrupt)
c8dfc6
and one which is used for raising an irq only.
c8dfc6
c8dfc6
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
c8dfc6
---
c8dfc6
 hw/usb/hcd-xhci.c | 47 +++++++++++++++++++++++++++++++++--------------
c8dfc6
 1 file changed, 33 insertions(+), 14 deletions(-)
c8dfc6
c8dfc6
diff --git a/hw/usb/hcd-xhci.c b/hw/usb/hcd-xhci.c
c8dfc6
index e1d5d2a..5eae32e 100644
c8dfc6
--- a/hw/usb/hcd-xhci.c
c8dfc6
+++ b/hw/usb/hcd-xhci.c
c8dfc6
@@ -612,24 +612,43 @@ static XHCIPort *xhci_lookup_port(XHCIState *xhci, struct USBPort *uport)
c8dfc6
     return &xhci->ports[index];
c8dfc6
 }
c8dfc6
 
c8dfc6
-static void xhci_irq_update(XHCIState *xhci)
c8dfc6
+static void xhci_intx_update(XHCIState *xhci)
c8dfc6
 {
c8dfc6
     int level = 0;
c8dfc6
 
c8dfc6
-    if (xhci->iman & IMAN_IP && xhci->iman & IMAN_IE &&
c8dfc6
+    if (msi_enabled(&xhci->pci_dev)) {
c8dfc6
+        return;
c8dfc6
+    }
c8dfc6
+
c8dfc6
+    if (xhci->iman & IMAN_IP &&
c8dfc6
+        xhci->iman & IMAN_IE &&
c8dfc6
         xhci->usbcmd & USBCMD_INTE) {
c8dfc6
         level = 1;
c8dfc6
     }
c8dfc6
 
c8dfc6
+    trace_usb_xhci_irq_intx(level);
c8dfc6
+    qemu_set_irq(xhci->irq, level);
c8dfc6
+}
c8dfc6
+
c8dfc6
+static void xhci_intr_raise(XHCIState *xhci)
c8dfc6
+{
c8dfc6
+    if (!(xhci->iman & IMAN_IP) ||
c8dfc6
+        !(xhci->iman & IMAN_IE)) {
c8dfc6
+        return;
c8dfc6
+    }
c8dfc6
+
c8dfc6
+    if (!(xhci->usbcmd & USBCMD_INTE)) {
c8dfc6
+        return;
c8dfc6
+    }
c8dfc6
+
c8dfc6
     if (msi_enabled(&xhci->pci_dev)) {
c8dfc6
-        if (level) {
c8dfc6
-            trace_usb_xhci_irq_msi(0);
c8dfc6
-            msi_notify(&xhci->pci_dev, 0);
c8dfc6
-        }
c8dfc6
-    } else {
c8dfc6
-        trace_usb_xhci_irq_intx(level);
c8dfc6
-        qemu_set_irq(xhci->irq, level);
c8dfc6
+        trace_usb_xhci_irq_msi(0);
c8dfc6
+        msi_notify(&xhci->pci_dev, 0);
c8dfc6
+        return;
c8dfc6
     }
c8dfc6
+
c8dfc6
+    trace_usb_xhci_irq_intx(1);
c8dfc6
+    qemu_set_irq(xhci->irq, 1);
c8dfc6
 }
c8dfc6
 
c8dfc6
 static inline int xhci_running(XHCIState *xhci)
c8dfc6
@@ -732,7 +751,7 @@ static void xhci_events_update(XHCIState *xhci)
c8dfc6
         xhci->erdp_low |= ERDP_EHB;
c8dfc6
         xhci->iman |= IMAN_IP;
c8dfc6
         xhci->usbsts |= USBSTS_EINT;
c8dfc6
-        xhci_irq_update(xhci);
c8dfc6
+        xhci_intr_raise(xhci);
c8dfc6
     }
c8dfc6
 
c8dfc6
     if (xhci->er_full && xhci->ev_buffer_put == xhci->ev_buffer_get) {
c8dfc6
@@ -796,7 +815,7 @@ static void xhci_event(XHCIState *xhci, XHCIEvent *event)
c8dfc6
     xhci->iman |= IMAN_IP;
c8dfc6
     xhci->usbsts |= USBSTS_EINT;
c8dfc6
 
c8dfc6
-    xhci_irq_update(xhci);
c8dfc6
+    xhci_intr_raise(xhci);
c8dfc6
 }
c8dfc6
 
c8dfc6
 static void xhci_ring_init(XHCIState *xhci, XHCIRing *ring,
c8dfc6
@@ -2481,13 +2500,13 @@ static void xhci_oper_write(XHCIState *xhci, uint32_t reg, uint32_t val)
c8dfc6
         if (val & USBCMD_HCRST) {
c8dfc6
             xhci_reset(&xhci->pci_dev.qdev);
c8dfc6
         }
c8dfc6
-        xhci_irq_update(xhci);
c8dfc6
+        xhci_intx_update(xhci);
c8dfc6
         break;
c8dfc6
 
c8dfc6
     case 0x04: /* USBSTS */
c8dfc6
         /* these bits are write-1-to-clear */
c8dfc6
         xhci->usbsts &= ~(val & (USBSTS_HSE|USBSTS_EINT|USBSTS_PCD|USBSTS_SRE));
c8dfc6
-        xhci_irq_update(xhci);
c8dfc6
+        xhci_intx_update(xhci);
c8dfc6
         break;
c8dfc6
 
c8dfc6
     case 0x14: /* DNCTRL */
c8dfc6
@@ -2572,7 +2591,7 @@ static void xhci_runtime_write(XHCIState *xhci, uint32_t reg, uint32_t val)
c8dfc6
         }
c8dfc6
         xhci->iman &= ~IMAN_IE;
c8dfc6
         xhci->iman |= val & IMAN_IE;
c8dfc6
-        xhci_irq_update(xhci);
c8dfc6
+        xhci_intx_update(xhci);
c8dfc6
         break;
c8dfc6
     case 0x24: /* IMOD */
c8dfc6
         xhci->imod = val;
c8dfc6
-- 
c8dfc6
1.7.12
c8dfc6