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

5544c1
From 3bf435b656390f75ce8b8990f7484efb162472c9 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
5544c1
Subject: [PATCH] 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
5544c1
index d2e6ee6..1857f42 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,
5544c1
@@ -2479,13 +2498,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 */
5544c1
@@ -2570,7 +2589,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
-- 
5544c1
1.7.12.1
Hans de Goede c8dfc6