dcavalca / rpms / qemu

Forked from rpms/qemu 11 months ago
Clone

Blame 0128-usb-ehci-split-our-qh-queue-into-async-and-periodic-.patch

Hans de Goede 1b1995
From 0f1e5b8d4f36de8b6b1301740226c9858b5a0318 Mon Sep 17 00:00:00 2001
Hans de Goede 1b1995
From: Hans de Goede <hdegoede@redhat.com>
Hans de Goede 1b1995
Date: Tue, 28 Feb 2012 16:34:38 +0100
Hans de Goede 1b1995
Subject: [PATCH 128/140] usb-ehci: split our qh queue into async and periodic
Hans de Goede 1b1995
 queues
Hans de Goede 1b1995
Hans de Goede 1b1995
qhs can be part of both the async and the periodic schedule, as is shown
Hans de Goede 1b1995
in later patches in this series it is useful to keep track of the qhs on
Hans de Goede 1b1995
a per schedule basis.
Hans de Goede 1b1995
Hans de Goede 1b1995
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Hans de Goede 1b1995
---
Hans de Goede 1b1995
 hw/usb-ehci.c |   62 ++++++++++++++++++++++++++++++++++-----------------------
Hans de Goede 1b1995
 1 file changed, 37 insertions(+), 25 deletions(-)
Hans de Goede 1b1995
Hans de Goede 1b1995
diff --git a/hw/usb-ehci.c b/hw/usb-ehci.c
Hans de Goede 1b1995
index 37076a9..980cce3 100644
Hans de Goede 1b1995
--- a/hw/usb-ehci.c
Hans de Goede 1b1995
+++ b/hw/usb-ehci.c
Hans de Goede 1b1995
@@ -347,7 +347,6 @@ enum async_state {
Hans de Goede 1b1995
 struct EHCIQueue {
Hans de Goede 1b1995
     EHCIState *ehci;
Hans de Goede 1b1995
     QTAILQ_ENTRY(EHCIQueue) next;
Hans de Goede 1b1995
-    bool async_schedule;
Hans de Goede 1b1995
     uint32_t seen;
Hans de Goede 1b1995
     uint64_t ts;
Hans de Goede 1b1995
 
Hans de Goede 1b1995
@@ -367,6 +366,8 @@ struct EHCIQueue {
Hans de Goede 1b1995
     int usb_status;
Hans de Goede 1b1995
 };
Hans de Goede 1b1995
 
Hans de Goede 1b1995
+typedef QTAILQ_HEAD(EHCIQueueHead, EHCIQueue) EHCIQueueHead;
Hans de Goede 1b1995
+
Hans de Goede 1b1995
 struct EHCIState {
Hans de Goede 1b1995
     PCIDevice dev;
Hans de Goede 1b1995
     USBBus bus;
Hans de Goede 1b1995
@@ -410,7 +411,8 @@ struct EHCIState {
Hans de Goede 1b1995
     USBPort ports[NB_PORTS];
Hans de Goede 1b1995
     USBPort *companion_ports[NB_PORTS];
Hans de Goede 1b1995
     uint32_t usbsts_pending;
Hans de Goede 1b1995
-    QTAILQ_HEAD(, EHCIQueue) queues;
Hans de Goede 1b1995
+    EHCIQueueHead aqueues;
Hans de Goede 1b1995
+    EHCIQueueHead pqueues;
Hans de Goede 1b1995
 
Hans de Goede 1b1995
     uint32_t a_fetch_addr;   // which address to look at next
Hans de Goede 1b1995
     uint32_t p_fetch_addr;   // which address to look at next
Hans de Goede 1b1995
@@ -660,31 +662,34 @@ static void ehci_trace_sitd(EHCIState *s, target_phys_addr_t addr,
Hans de Goede 1b1995
 
Hans de Goede 1b1995
 static EHCIQueue *ehci_alloc_queue(EHCIState *ehci, int async)
Hans de Goede 1b1995
 {
Hans de Goede 1b1995
+    EHCIQueueHead *head = async ? &ehci->aqueues : &ehci->pqueues;
Hans de Goede 1b1995
     EHCIQueue *q;
Hans de Goede 1b1995
 
Hans de Goede 1b1995
     q = g_malloc0(sizeof(*q));
Hans de Goede 1b1995
     q->ehci = ehci;
Hans de Goede 1b1995
-    q->async_schedule = async;
Hans de Goede 1b1995
-    QTAILQ_INSERT_HEAD(&ehci->queues, q, next);
Hans de Goede 1b1995
+    QTAILQ_INSERT_HEAD(head, q, next);
Hans de Goede 1b1995
     trace_usb_ehci_queue_action(q, "alloc");
Hans de Goede 1b1995
     return q;
Hans de Goede 1b1995
 }
Hans de Goede 1b1995
 
Hans de Goede 1b1995
-static void ehci_free_queue(EHCIQueue *q)
Hans de Goede 1b1995
+static void ehci_free_queue(EHCIQueue *q, int async)
Hans de Goede 1b1995
 {
Hans de Goede 1b1995
+    EHCIQueueHead *head = async ? &q->ehci->aqueues : &q->ehci->pqueues;
Hans de Goede 1b1995
     trace_usb_ehci_queue_action(q, "free");
Hans de Goede 1b1995
     if (q->async == EHCI_ASYNC_INFLIGHT) {
Hans de Goede 1b1995
         usb_cancel_packet(&q->packet);
Hans de Goede 1b1995
     }
Hans de Goede 1b1995
-    QTAILQ_REMOVE(&q->ehci->queues, q, next);
Hans de Goede 1b1995
+    QTAILQ_REMOVE(head, q, next);
Hans de Goede 1b1995
     g_free(q);
Hans de Goede 1b1995
 }
Hans de Goede 1b1995
 
Hans de Goede 1b1995
-static EHCIQueue *ehci_find_queue_by_qh(EHCIState *ehci, uint32_t addr)
Hans de Goede 1b1995
+static EHCIQueue *ehci_find_queue_by_qh(EHCIState *ehci, uint32_t addr,
Hans de Goede 1b1995
+                                        int async)
Hans de Goede 1b1995
 {
Hans de Goede 1b1995
+    EHCIQueueHead *head = async ? &ehci->aqueues : &ehci->pqueues;
Hans de Goede 1b1995
     EHCIQueue *q;
Hans de Goede 1b1995
 
Hans de Goede 1b1995
-    QTAILQ_FOREACH(q, &ehci->queues, next) {
Hans de Goede 1b1995
+    QTAILQ_FOREACH(q, head, next) {
Hans de Goede 1b1995
         if (addr == q->qhaddr) {
Hans de Goede 1b1995
             return q;
Hans de Goede 1b1995
         }
Hans de Goede 1b1995
@@ -692,11 +697,12 @@ static EHCIQueue *ehci_find_queue_by_qh(EHCIState *ehci, uint32_t addr)
Hans de Goede 1b1995
     return NULL;
Hans de Goede 1b1995
 }
Hans de Goede 1b1995
 
Hans de Goede 1b1995
-static void ehci_queues_rip_unused(EHCIState *ehci)
Hans de Goede 1b1995
+static void ehci_queues_rip_unused(EHCIState *ehci, int async)
Hans de Goede 1b1995
 {
Hans de Goede 1b1995
+    EHCIQueueHead *head = async ? &ehci->aqueues : &ehci->pqueues;
Hans de Goede 1b1995
     EHCIQueue *q, *tmp;
Hans de Goede 1b1995
 
Hans de Goede 1b1995
-    QTAILQ_FOREACH_SAFE(q, &ehci->queues, next, tmp) {
Hans de Goede 1b1995
+    QTAILQ_FOREACH_SAFE(q, head, next, tmp) {
Hans de Goede 1b1995
         if (q->seen) {
Hans de Goede 1b1995
             q->seen = 0;
Hans de Goede 1b1995
             q->ts = ehci->last_run_ns;
Hans de Goede 1b1995
@@ -706,28 +712,30 @@ static void ehci_queues_rip_unused(EHCIState *ehci)
Hans de Goede 1b1995
             /* allow 0.25 sec idle */
Hans de Goede 1b1995
             continue;
Hans de Goede 1b1995
         }
Hans de Goede 1b1995
-        ehci_free_queue(q);
Hans de Goede 1b1995
+        ehci_free_queue(q, async);
Hans de Goede 1b1995
     }
Hans de Goede 1b1995
 }
Hans de Goede 1b1995
 
Hans de Goede 1b1995
-static void ehci_queues_rip_device(EHCIState *ehci, USBDevice *dev)
Hans de Goede 1b1995
+static void ehci_queues_rip_device(EHCIState *ehci, USBDevice *dev, int async)
Hans de Goede 1b1995
 {
Hans de Goede 1b1995
+    EHCIQueueHead *head = async ? &ehci->aqueues : &ehci->pqueues;
Hans de Goede 1b1995
     EHCIQueue *q, *tmp;
Hans de Goede 1b1995
 
Hans de Goede 1b1995
-    QTAILQ_FOREACH_SAFE(q, &ehci->queues, next, tmp) {
Hans de Goede 1b1995
+    QTAILQ_FOREACH_SAFE(q, head, next, tmp) {
Hans de Goede 1b1995
         if (q->packet.owner != dev) {
Hans de Goede 1b1995
             continue;
Hans de Goede 1b1995
         }
Hans de Goede 1b1995
-        ehci_free_queue(q);
Hans de Goede 1b1995
+        ehci_free_queue(q, async);
Hans de Goede 1b1995
     }
Hans de Goede 1b1995
 }
Hans de Goede 1b1995
 
Hans de Goede 1b1995
-static void ehci_queues_rip_all(EHCIState *ehci)
Hans de Goede 1b1995
+static void ehci_queues_rip_all(EHCIState *ehci, int async)
Hans de Goede 1b1995
 {
Hans de Goede 1b1995
+    EHCIQueueHead *head = async ? &ehci->aqueues : &ehci->pqueues;
Hans de Goede 1b1995
     EHCIQueue *q, *tmp;
Hans de Goede 1b1995
 
Hans de Goede 1b1995
-    QTAILQ_FOREACH_SAFE(q, &ehci->queues, next, tmp) {
Hans de Goede 1b1995
-        ehci_free_queue(q);
Hans de Goede 1b1995
+    QTAILQ_FOREACH_SAFE(q, head, next, tmp) {
Hans de Goede 1b1995
+        ehci_free_queue(q, async);
Hans de Goede 1b1995
     }
Hans de Goede 1b1995
 }
Hans de Goede 1b1995
 
Hans de Goede 1b1995
@@ -772,7 +780,8 @@ static void ehci_detach(USBPort *port)
Hans de Goede 1b1995
         return;
Hans de Goede 1b1995
     }
Hans de Goede 1b1995
 
Hans de Goede 1b1995
-    ehci_queues_rip_device(s, port->dev);
Hans de Goede 1b1995
+    ehci_queues_rip_device(s, port->dev, 0);
Hans de Goede 1b1995
+    ehci_queues_rip_device(s, port->dev, 1);
Hans de Goede 1b1995
 
Hans de Goede 1b1995
     *portsc &= ~(PORTSC_CONNECT|PORTSC_PED);
Hans de Goede 1b1995
     *portsc |= PORTSC_CSC;
Hans de Goede 1b1995
@@ -792,7 +801,8 @@ static void ehci_child_detach(USBPort *port, USBDevice *child)
Hans de Goede 1b1995
         return;
Hans de Goede 1b1995
     }
Hans de Goede 1b1995
 
Hans de Goede 1b1995
-    ehci_queues_rip_device(s, child);
Hans de Goede 1b1995
+    ehci_queues_rip_device(s, child, 0);
Hans de Goede 1b1995
+    ehci_queues_rip_device(s, child, 1);
Hans de Goede 1b1995
 }
Hans de Goede 1b1995
 
Hans de Goede 1b1995
 static void ehci_wakeup(USBPort *port)
Hans de Goede 1b1995
@@ -890,7 +900,8 @@ static void ehci_reset(void *opaque)
Hans de Goede 1b1995
             usb_send_msg(devs[i], USB_MSG_RESET);
Hans de Goede 1b1995
         }
Hans de Goede 1b1995
     }
Hans de Goede 1b1995
-    ehci_queues_rip_all(s);
Hans de Goede 1b1995
+    ehci_queues_rip_all(s, 0);
Hans de Goede 1b1995
+    ehci_queues_rip_all(s, 1);
Hans de Goede 1b1995
 }
Hans de Goede 1b1995
 
Hans de Goede 1b1995
 static uint32_t ehci_mem_readb(void *ptr, target_phys_addr_t addr)
Hans de Goede 1b1995
@@ -1554,7 +1565,7 @@ static int ehci_state_waitlisthead(EHCIState *ehci,  int async)
Hans de Goede 1b1995
         ehci_set_usbsts(ehci, USBSTS_REC);
Hans de Goede 1b1995
     }
Hans de Goede 1b1995
 
Hans de Goede 1b1995
-    ehci_queues_rip_unused(ehci);
Hans de Goede 1b1995
+    ehci_queues_rip_unused(ehci, async);
Hans de Goede 1b1995
 
Hans de Goede 1b1995
     /*  Find the head of the list (4.9.1.1) */
Hans de Goede 1b1995
     for(i = 0; i < MAX_QH; i++) {
Hans de Goede 1b1995
@@ -1641,7 +1652,7 @@ static EHCIQueue *ehci_state_fetchqh(EHCIState *ehci, int async)
Hans de Goede 1b1995
     int reload;
Hans de Goede 1b1995
 
Hans de Goede 1b1995
     entry = ehci_get_fetch_addr(ehci, async);
Hans de Goede 1b1995
-    q = ehci_find_queue_by_qh(ehci, entry);
Hans de Goede 1b1995
+    q = ehci_find_queue_by_qh(ehci, entry, async);
Hans de Goede 1b1995
     if (NULL == q) {
Hans de Goede 1b1995
         q = ehci_alloc_queue(ehci, async);
Hans de Goede 1b1995
     }
Hans de Goede 1b1995
@@ -2092,7 +2103,7 @@ static void ehci_advance_state(EHCIState *ehci,
Hans de Goede 1b1995
 
Hans de Goede 1b1995
 static void ehci_advance_async_state(EHCIState *ehci)
Hans de Goede 1b1995
 {
Hans de Goede 1b1995
-    int async = 1;
Hans de Goede 1b1995
+    const int async = 1;
Hans de Goede 1b1995
 
Hans de Goede 1b1995
     switch(ehci_get_state(ehci, async)) {
Hans de Goede 1b1995
     case EST_INACTIVE:
Hans de Goede 1b1995
@@ -2149,7 +2160,7 @@ static void ehci_advance_periodic_state(EHCIState *ehci)
Hans de Goede 1b1995
 {
Hans de Goede 1b1995
     uint32_t entry;
Hans de Goede 1b1995
     uint32_t list;
Hans de Goede 1b1995
-    int async = 0;
Hans de Goede 1b1995
+    const int async = 0;
Hans de Goede 1b1995
 
Hans de Goede 1b1995
     // 4.6
Hans de Goede 1b1995
 
Hans de Goede 1b1995
@@ -2366,7 +2377,8 @@ static int usb_ehci_initfn(PCIDevice *dev)
Hans de Goede 1b1995
     }
Hans de Goede 1b1995
 
Hans de Goede 1b1995
     s->frame_timer = qemu_new_timer_ns(vm_clock, ehci_frame_timer, s);
Hans de Goede 1b1995
-    QTAILQ_INIT(&s->queues);
Hans de Goede 1b1995
+    QTAILQ_INIT(&s->aqueues);
Hans de Goede 1b1995
+    QTAILQ_INIT(&s->pqueues);
Hans de Goede 1b1995
 
Hans de Goede 1b1995
     qemu_register_reset(ehci_reset, s);
Hans de Goede 1b1995
 
Hans de Goede 1b1995
-- 
Hans de Goede 1b1995
1.7.9.3
Hans de Goede 1b1995