dcavalca / rpms / qemu

Forked from rpms/qemu a year ago
Clone

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

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